Просмотр исходного кода

* Add a -d|--chdir option to start-stop-daemon.
* Split the background block into 2 parts: one that does the fork, and
opens /dev/tty and /dev/null, and one that does everything else. The
second block is then moved to be run right before the exec. This allows
error messages to be seen from the child(previously, they were lost), and
allows for the chroot to not require the device files.
* When --start, --startas and --pidfile are given, print 'process' instead
of '(null)' for the process name, if it's already running.

Adam Heath лет назад: 23
Родитель
Сommit
65517fd021
4 измененных файлов с 91 добавлено и 43 удалено
  1. 12 0
      ChangeLog
  2. 16 1
      debian/changelog
  3. 6 0
      utils/start-stop-daemon.8
  4. 57 42
      utils/start-stop-daemon.c

+ 12 - 0
ChangeLog

@@ -1,3 +1,15 @@
+Sat Sep 20 18:45:11 CDT 2003 Adam Heath <doogie@debian.org>
+
+  * utils/start-stop-daemon.[c8]:
+    * Add a -d|--chdir option to start-stop-daemon.
+    * Split the background block into 2 parts: one that does the fork, and
+      opens /dev/tty and /dev/null, and one that does everything else.  The
+      second block is then moved to be run right before the exec.  This
+      allows error messages to be seen from the child(previously, they were
+      lost), and allows for the chroot to not require the device files.
+    * When --start, --startas and --pidfile are given, print 'process'
+      instead of '(null)' for the process name, if it's already running.
+
 Sat Sep 20 17:44:40 CDT 2003 Adam Heath <doogie@debian.org>
 
   * configure.in, include/dpkg.h.in: Fix (non-)detection of setlocale.

+ 16 - 1
debian/changelog

@@ -1,6 +1,21 @@
 dpkg (1.10.16) unstable; urgency=low
 
-  * Fix configure to set HAVE_SETLOCALE.  Closes: #211816
+  * Jordi Mallach <jordi@debian.org>:
+    Fix configure to set HAVE_SETLOCALE.  Closes: #211816
+  * "Loïc Le Loarer" <lll_deb@m4x.org>:
+    Add a -d|--chdir option to start-stop-daemon.  Closes: #151802
+  * Split the background block into 2 parts: one that does the fork, and
+    opens /dev/tty and /dev/null, and one that does everything else.  The
+    second block is then moved to be run right before the exec.  This
+    allows error messages to be seen from the child(previously, they were
+    lost), and allows for the chroot to not require the device files.
+    These changes based on the bugs filed by:
+    Marc Herbert <Marc.Herbert@ens-lyon.fr>: Closes: #155219
+    Loïc Le Loarer <lll_deb@m4x.org>: Closes: #151800
+  * Mario Lang <mlang@debian.org>:
+    When --start, --startas and --pidfile are given, print 'process'
+    instead of '(null)' for the process name, if it's already running.
+    Closes: #209355
 
  -- Adam Heath <doogie@debian.org>  UNRELEASED
 

+ 6 - 0
utils/start-stop-daemon.8

@@ -184,6 +184,12 @@ Chdir and chroot to
 before starting the process. Please note that the pidfile is also written
 after the chroot.
 .TP
+\fB-d\fP|\fB--chdir\fP \fIpath\fP
+Chdir to
+.I path
+before starting the process. This is done after the chroot if the
+\fB-r\fP|\fB--chroot\fP option is set.
+.TP
 .BR -b | --background
 Typically used with programs that don't detach on their own. This option
 will force

+ 57 - 42
utils/start-stop-daemon.c

@@ -109,6 +109,7 @@ static const char *userspec = NULL;
 static char *changeuser = NULL;
 static const char *changegroup = NULL;
 static char *changeroot = NULL;
+static const char *changedir = "/";
 static const char *cmdname = NULL;
 static char *execname = NULL;
 static char *startas = NULL;
@@ -278,6 +279,7 @@ do_help(void)
 "  -n|--name <process-name>      stop processes with this name\n"
 "  -s|--signal <signal>          signal to send (default TERM)\n"
 "  -a|--startas <pathname>       program to start (default is <executable>)\n"
+"  -C|--chdir <directory>        Change to <directory>(default is /)\n"
 "  -N|--nicelevel <incr>         add incr to the process's nice level\n"
 "  -b|--background               force the process to detach\n"
 "  -m|--make-pidfile             create the pidfile before starting\n"
@@ -466,12 +468,13 @@ parse_options(int argc, char * const *argv)
 		{ "background",   0, NULL, 'b'},
 		{ "make-pidfile", 0, NULL, 'm'},
  		{ "retry",        1, NULL, 'R'},
+		{ "chdir",        1, NULL, 'd'},
 		{ NULL,		0, NULL, 0}
 	};
 	int c;
 
 	for (;;) {
-		c = getopt_long(argc, argv, "HKSVa:n:op:qr:s:tu:vx:c:N:bmR:g:",
+		c = getopt_long(argc, argv, "HKSV:a:n:op:qr:s:tu:vx:c:N:bmR:g:d:",
 				longopts, (int *) 0);
 		if (c == -1)
 			break;
@@ -543,6 +546,9 @@ parse_options(int argc, char * const *argv)
 		case 'R':  /* --retry <schedule>|<timeout> */
 			schedule_str = optarg;
 			break;
+		case 'd':  /* --chdir /new/dir */
+			changedir = optarg;
+			break;
 		default:
 			badusage(NULL);  /* message printed by getopt */
 		}
@@ -1122,6 +1128,10 @@ int main(int argc, char **argv) NONRETURNING;
 int
 main(int argc, char **argv)
 {
+	int devnull_fd = -1;
+#ifdef HAVE_TIOCNOTTY
+	int tty_fd = -1;
+#endif
 	progname = argv[0];
 
 	parse_options(argc, argv);
@@ -1167,7 +1177,7 @@ main(int argc, char **argv)
 
 	if (found) {
 		if (quietmode <= 0)
-			printf("%s already running.\n", execname);
+			printf("%s already running.\n", execname ? execname : "process");
 		exit(exitnodo);
 	}
 	if (testmode) {
@@ -1191,23 +1201,8 @@ main(int argc, char **argv)
 	if (quietmode < 0)
 		printf("Starting %s...\n", startas);
 	*--argv = startas;
-	if (changeroot != NULL) {
-		if (chdir(changeroot) < 0)
-			fatal("Unable to chdir() to %s", changeroot);
-		if (chroot(changeroot) < 0)
-			fatal("Unable to chroot() to %s", changeroot);
-	}
-	if (changeuser != NULL) {
- 		if (setgid(runas_gid))
- 			fatal("Unable to set gid to %d", runas_gid);
-		if (initgroups(changeuser, runas_gid))
-			fatal("Unable to set initgroups() with gid %d", runas_gid);
-		if (setuid(runas_uid))
-			fatal("Unable to set uid to %s", changeuser);
-	}
-
 	if (background) { /* ok, we need to detach this process */
-		int i, fd;
+		int i;
 		if (quietmode < 0)
 			printf("Detatching to start %s...", startas);
 		i = fork();
@@ -1221,32 +1216,10 @@ main(int argc, char **argv)
 		}
 		 /* child continues here */
 
-		/* create a new session */
-#ifdef HAVE_SETSID
-		setsid();
-#else
-		setpgid(0,0);
-#endif
-
-#if defined(OShpux)
-		 /* now close all extra fds */
-		for (i=sysconf(_SC_OPEN_MAX)-1; i>=0; --i) close(i);
-#else
-		 /* now close all extra fds */
-		for (i=getdtablesize()-1; i>=0; --i) close(i);
-#endif
-
 #ifdef HAVE_TIOCNOTTY
-		 /* change tty */
-		fd = open("/dev/tty", O_RDWR);
-		ioctl(fd, TIOCNOTTY, 0);
-		close(fd);
+		tty_fd=open("/dev/tty", O_RDWR);
 #endif
-		chdir("/");
-		umask(022); /* set a default for dumb programs */
-		fd=open("/dev/null", O_RDWR); /* stdin */
-		dup(fd); /* stdout */
-		dup(fd); /* stderr */
+		devnull_fd=open("/dev/null", O_RDWR);
 	}
 	if (nicelevel) {
 		errno=0;
@@ -1263,6 +1236,48 @@ main(int argc, char **argv)
 		fprintf(pidf, "%d\n", pidt);
 		fclose(pidf);
 	}
+	if (changeroot != NULL) {
+		if (chdir(changeroot) < 0)
+			fatal("Unable to chdir() to %s", changeroot);
+		if (chroot(changeroot) < 0)
+			fatal("Unable to chroot() to %s", changeroot);
+	}
+	if (chdir(changedir) < 0)
+		fatal("Unable to chdir() to %s", changedir);
+	if (changeuser != NULL) {
+ 		if (setgid(runas_gid))
+ 			fatal("Unable to set gid to %d", runas_gid);
+		if (initgroups(changeuser, runas_gid))
+			fatal("Unable to set initgroups() with gid %d", runas_gid);
+		if (setuid(runas_uid))
+			fatal("Unable to set uid to %s", changeuser);
+	}
+	if (background) { /* continue background setup */
+		int i;
+#ifdef HAVE_TIOCNOTTY
+		 /* change tty */
+		ioctl(tty_fd, TIOCNOTTY, 0);
+		close(tty_fd);
+#endif
+		umask(022); /* set a default for dumb programs */
+		dup2(devnull_fd,0); /* stdin */
+		dup2(devnull_fd,1); /* stdout */
+		dup2(devnull_fd,2); /* stderr */
+#if defined(OShpux)
+		 /* now close all extra fds */
+		for (i=sysconf(_SC_OPEN_MAX)-1; i>=3; --i) close(i);
+#else
+		 /* now close all extra fds */
+		for (i=getdtablesize()-1; i>=3; --i) close(i);
+#endif
+
+		/* create a new session */
+#ifdef HAVE_SETSID
+		setsid();
+#else
+		setpgid(0,0);
+#endif
+	}
 	execv(startas, argv);
 	fatal("Unable to start %s: %s", startas, strerror(errno));
 }