Browse Source

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>
ejaaskel 5 months ago
parent
commit
73f28134fc
3 changed files with 41 additions and 15 deletions
  1. 0 2
      TODO
  2. 21 13
      debianutils/start_stop_daemon.c
  3. 20 0
      testsuite/start-stop-daemon.tests

+ 0 - 2
TODO

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

+ 21 - 13
debianutils/start_stop_daemon.c

@@ -11,7 +11,7 @@
 /*
 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:
         -S,--start              Start
@@ -58,13 +58,14 @@ Options which are valid for --start only:
                                 priority can be optionally specified by appending a :
                                 followed by the value. The default priority is 0. The
                                 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
                                 the chroot.
-        -d,--chdir path         Change directory to path before starting the process. This is
-                                done after the chroot if the -r|--chroot option is set. When
-                                not specified, start-stop-daemon will change directory to the
+        -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 not specified, start-stop-daemon will change directory to the
                                 root directory before starting the process.
+                                ^^^^ Seems to be false, no default "/" chdir is done.
 
 Options which are valid for --stop only:
         -s,--signal SIG         Signal to send (default:TERM)
@@ -106,7 +107,7 @@ Misc options:
 //kbuild:lib-$(CONFIG_START_STOP_DAEMON) += start_stop_daemon.o
 
 //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:       "Search for matching processes, and then\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:	)
 //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-K only:"
 //usage:     "\n	-s SIG		Signal to send"
@@ -160,11 +162,12 @@ enum {
 	OPT_s          = (1 <<  8), // -s
 	OPT_u          = (1 <<  9), // -u
 	OPT_c          = (1 << 10), // -c
-	OPT_x          = (1 << 11), // -x
-	OPT_p          = (1 << 12), // -p
-	OPT_OKNODO     = (1 << 13) * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, // -o
-	OPT_VERBOSE    = (1 << 14) * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, // -v
-	OPT_NICELEVEL  = (1 << 15) * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, // -N
+	OPT_d          = (1 << 11), // -d
+	OPT_x          = (1 << 12), // -x
+	OPT_p          = (1 << 13), // -p
+	OPT_OKNODO     = (1 << 14) * ENABLE_FEATURE_START_STOP_DAEMON_FANCY, // -o
+	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 TEST  (option_mask32 & OPT_TEST)
@@ -413,6 +416,7 @@ static const char start_stop_daemon_longopts[] ALIGN1 =
 	"signal\0"       Required_argument "s"
 	"user\0"         Required_argument "u"
 	"chuid\0"        Required_argument "c"
+	"chdir\0"        Required_argument "d"
 	"exec\0"         Required_argument "x"
 	"pidfile\0"      Required_argument "p"
 # 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 *startas = NULL;
 	char *chuid;
+	char *chdir;
 #if ENABLE_FEATURE_START_STOP_DAEMON_FANCY
 //	char *retry_arg = NULL;
 //	int retries = -1;
@@ -442,7 +447,7 @@ int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv)
 	INIT_G();
 
 	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:")
 			"\0"
 			"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 */
 			,
 		LONGOPTS
-		&startas, &cmdname, &signame, &userspec, &chuid, &execname, &pidfile
+		&startas, &cmdname, &signame, &userspec, &chuid, &chdir, &execname, &pidfile
 		IF_FEATURE_START_STOP_DAEMON_FANCY(,&opt_N)
 		/* We accept and ignore -R <param> / --retry <param> */
 		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);
 		}
 	}
+	if (opt & OPT_d) {
+		xchdir(chdir);
+	}
 	/* Try:
 	 * strace -oLOG start-stop-daemon -S -x /bin/usleep -a qwerty 500000
 	 * should exec "/bin/usleep", but argv[0] should be "qwerty":

+ 20 - 0
testsuite/start-stop-daemon.tests

@@ -11,6 +11,21 @@ testing "start-stop-daemon -x without -a" \
 	"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" \
 	'start-stop-daemon -S -a false 2>&1; echo $?' \
 	"1\n" \
@@ -21,6 +36,11 @@ testing "start-stop-daemon without -x and -a" \
 	"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 }.
 #
 # Unfortunately, this does not actually check argv[0] correctness,