[Midnightbsd-cvs] src [7641] trunk/usr.sbin/daemon: sync daemon(3) with freebsd 10 stable.

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sat Jun 25 22:16:18 EDT 2016


Revision: 7641
          http://svnweb.midnightbsd.org/src/?rev=7641
Author:   laffer1
Date:     2016-06-25 22:16:17 -0400 (Sat, 25 Jun 2016)
Log Message:
-----------
sync daemon(3) with freebsd 10 stable. note the new -P flag

Modified Paths:
--------------
    trunk/usr.sbin/daemon/daemon.8
    trunk/usr.sbin/daemon/daemon.c

Modified: trunk/usr.sbin/daemon/daemon.8
===================================================================
--- trunk/usr.sbin/daemon/daemon.8	2016-06-26 00:25:57 UTC (rev 7640)
+++ trunk/usr.sbin/daemon/daemon.8	2016-06-26 02:16:17 UTC (rev 7641)
@@ -25,8 +25,9 @@
 .\" SUCH DAMAGE.
 .\"
 .\" $MidnightBSD$
+.\" $FreeBSD: stable/10/usr.sbin/daemon/daemon.8 255526 2013-09-13 19:19:21Z joel $
 .\"
-.Dd June 4, 2012
+.Dd September 13, 2013
 .Dt DAEMON 8
 .Os
 .Sh NAME
@@ -35,7 +36,8 @@
 .Sh SYNOPSIS
 .Nm
 .Op Fl cfr
-.Op Fl p Ar pidfile
+.Op Fl p Ar child_pidfile
+.Op Fl P Ar supervisor_pidfile
 .Op Fl u Ar user
 .Ar command arguments ...
 .Sh DESCRIPTION
@@ -53,9 +55,9 @@
 .It Fl f
 Redirect standard input, standard output and standard error to
 .Pa /dev/null .
-.It Fl p Ar file
+.It Fl p Ar child_pidfile
 Write the ID of the created process into the
-.Ar file
+.Ar child_pidfile
 using the
 .Xr pidfile 3
 functionality.
@@ -62,15 +64,35 @@
 The program is executed in a spawned child process while the
 .Nm
 waits until it terminates to keep the
-.Ar file
+.Ar child_pidfile
 locked and removes it after the process exits.
 The
-.Ar file
+.Ar child_pidfile
 owner is the user who runs the
 .Nm
 regardless of whether the
 .Fl u
 option is used or not.
+.It Fl P Ar supervisor_pidfile
+Write the ID of the
+.Nm
+process into the
+.Ar supervisor_pidfile
+using the
+.Xr pidfile 3
+functionality.
+The program is executed in a spawned child process while the
+.Nm
+waits until it terminates to keep the
+.Ar supervisor_pidfile
+locked and removes it after the process exits.
+The
+.Ar supervisor_pidfile
+owner is the user who runs the
+.Nm
+regardless of whether the
+.Fl u
+option is used or not.
 .It Fl r
 Supervise and restart the program if it has been terminated.
 .It Fl u Ar user
@@ -79,27 +101,46 @@
 .El
 .Pp
 If the
-.Fl p
+.Fl p ,
+.Fl P
 or
 .Fl r
 option is specified the program is executed in a spawned child process.
 The
 .Nm
-waits until it terminates to keep the pid file locked and removes it
+waits until it terminates to keep the pid file(s) locked and removes them
 after the process exits or restarts the program.
 In this case if the monitoring
 .Nm
 receives software termination signal (SIGTERM) it forwards it to the
 spawned process.
-Normally it will cause the child to exit followed by the termination
-of the supervising process after removing the pidfile.
+Normally it will cause the child to exit, remove the pidfile(s)
+and then terminate.
+.Pp
+The
+.Fl P
+option is useful combined with the
+.Fl r
+option as
+.Ar supervisor_pidfile
+contains the ID of the supervisor
+not the child. This is especially important if you use
+.Fl r
+in an rc script as the
+.Fl p
+option will give you the child's ID to signal when you attempt to
+stop the service, causing
+.Nm
+to restart the child.
 .Sh EXIT STATUS
 The
 .Nm
 utility exits 1 if an error is returned by the
 .Xr daemon 3
-library routine, 2 if the
-.Ar pidfile
+library routine, 2 if
+.Ar child_pidfile
+or
+.Ar supervisor_pidfile
 is requested, but cannot be opened, 3 if process is already running (pidfile
 exists and is locked),
 otherwise 0.

Modified: trunk/usr.sbin/daemon/daemon.c
===================================================================
--- trunk/usr.sbin/daemon/daemon.c	2016-06-26 00:25:57 UTC (rev 7640)
+++ trunk/usr.sbin/daemon/daemon.c	2016-06-26 02:16:17 UTC (rev 7641)
@@ -53,16 +53,16 @@
 int
 main(int argc, char *argv[])
 {
-	struct pidfh *pfh = NULL;
+	struct pidfh  *ppfh, *pfh;
 	sigset_t mask, oldmask;
-	int ch, nochdir, noclose, restart;
-	const char *pidfile, *user;
+	int ch, nochdir, noclose, restart, serrno;
+	const char *pidfile, *ppidfile,  *user;
 	pid_t otherpid, pid;
 
 	nochdir = noclose = 1;
 	restart = 0;
-	pidfile = user = NULL;
-	while ((ch = getopt(argc, argv, "cfp:ru:")) != -1) {
+	ppidfile = pidfile = user = NULL;
+	while ((ch = getopt(argc, argv, "cfp:P:ru:")) != -1) {
 		switch (ch) {
 		case 'c':
 			nochdir = 0;
@@ -73,6 +73,9 @@
 		case 'p':
 			pidfile = optarg;
 			break;
+		case 'P':
+			ppidfile = optarg;
+			break;
 		case 'r':
 			restart = 1;
 			break;
@@ -89,7 +92,7 @@
 	if (argc == 0)
 		usage();
 
-	pfh = NULL;
+	ppfh = pfh = NULL;
 	/*
 	 * Try to open the pidfile before calling daemon(3),
 	 * to be able to report the error intelligently
@@ -104,9 +107,27 @@
 			err(2, "pidfile ``%s''", pidfile);
 		}
 	}
+	/* Do the same for actual daemon process. */
+	if (ppidfile != NULL) {
+		ppfh = pidfile_open(ppidfile, 0600, &otherpid);
+		if (ppfh == NULL) {
+			serrno = errno;
+			pidfile_remove(pfh);
+			errno = serrno;
+			if (errno == EEXIST) {
+				errx(3, "process already running, pid: %d",
+				     otherpid);
+			}
+			err(2, "ppidfile ``%s''", ppidfile);
+		}
+	}
 
-	if (daemon(nochdir, noclose) == -1)
-		err(1, NULL);
+	if (daemon(nochdir, noclose) == -1) {
+		warn("daemon");
+		goto exit;
+	}
+	/* Write out parent pidfile if needed. */
+	pidfile_write(ppfh);
 
 	/*
 	 * If the pidfile or restart option is specified the daemon
@@ -118,19 +139,23 @@
 	 * get SIGCHLD eventually.
 	 */
 	pid = -1;
-	if (pidfile != NULL || restart) {
+	if (pidfile != NULL || ppidfile != NULL || restart) {
 		/*
 		 * Restore default action for SIGTERM in case the
 		 * parent process decided to ignore it.
 		 */
-		if (signal(SIGTERM, SIG_DFL) == SIG_ERR)
-			err(1, "signal");
+		if (signal(SIGTERM, SIG_DFL) == SIG_ERR) {
+			warn("signal");
+			goto exit;
+		}
 		/*
 		 * Because SIGCHLD is ignored by default, setup dummy handler
 		 * for it, so we can mask it.
 		 */
-		if (signal(SIGCHLD, dummy_sighandler) == SIG_ERR)
-			err(1, "signal");
+		if (signal(SIGCHLD, dummy_sighandler) == SIG_ERR) {
+			warn("signal");
+			goto exit;
+		}
 		/*
 		 * Block interesting signals.
 		 */
@@ -137,8 +162,10 @@
 		sigemptyset(&mask);
 		sigaddset(&mask, SIGTERM);
 		sigaddset(&mask, SIGCHLD);
-		if (sigprocmask(SIG_SETMASK, &mask, &oldmask) == -1)
-			err(1, "sigprocmask");
+		if (sigprocmask(SIG_SETMASK, &mask, &oldmask) == -1) {
+			warn("sigprocmask");
+			goto exit;
+		}
 		/*
 		 * Try to protect against pageout kill. Ignore the
 		 * error, madvise(2) will fail only if a process does
@@ -152,8 +179,8 @@
 		 */
 		pid = fork();
 		if (pid == -1) {
-			pidfile_remove(pfh);
-			err(1, "fork");
+			warn("fork");
+			goto exit;
 		}
 	}
 	if (pid <= 0) {
@@ -176,13 +203,16 @@
 		 */
 		err(1, "%s", argv[0]);
 	}
+
 	setproctitle("%s[%d]", argv[0], pid);
 	if (wait_child(pid, &mask) == 0 && restart) {
 		sleep(1);
 		goto restart;
 	}
+exit:
 	pidfile_remove(pfh);
-	exit(0); /* Exit status does not matter. */
+	pidfile_remove(ppfh);
+	exit(1); /* If daemon(3) succeeded exit status does not matter. */
 }
 
 static void
@@ -240,7 +270,7 @@
 usage(void)
 {
 	(void)fprintf(stderr,
-	    "usage: daemon [-cfr] [-p pidfile] [-u user] command "
-		"arguments ...\n");
+	    "usage: daemon [-cfr] [-p child_pidfile] [-P supervisor_pidfile] "
+	    "[-u user]\n              command arguments ...\n");
 	exit(1);
 }



More information about the Midnightbsd-cvs mailing list