Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 06 Feb 2012 23:46:24 +0200
From:      Mikolaj Golub <trociny@freebsd.org>
To:        Pawel Jakub Dawidek <pjd@FreeBSD.org>
Cc:        svn-src-head@FreeBSD.org, Guy Helmer <ghelmer@palisadesystems.com>, svn-src-all@FreeBSD.org, Andrey Zonov <andrey@zonov.org>, src-committers@FreeBSD.org
Subject:   Re: svn commit: r230869 - head/usr.sbin/daemon
Message-ID:  <86wr7zmy8f.fsf@kopusha.home.net>
In-Reply-To: <20120206082706.GA1324@garage.freebsd.pl> (Pawel Jakub Dawidek's message of "Mon, 6 Feb 2012 09:27:06 %2B0100")
References:  <201202011641.q11Gf0j6095461@svn.freebsd.org> <20120204074201.GA1694@garage.freebsd.pl> <4F2CEB1D.10607@zonov.org> <27A0A960-F767-4D2C-BF3E-31F73FBF4E28@palisadesystems.com> <86zkcy5ur9.fsf@kopusha.home.net> <20120205093938.GC30033@garage.freebsd.pl> <86lioh7yz5.fsf@kopusha.home.net> <20120205214647.GI30033@garage.freebsd.pl> <86sjiov29o.fsf@in138.ua3> <20120206082706.GA1324@garage.freebsd.pl>

next in thread | previous in thread | raw e-mail | index | archive | help
--=-=-=


On Mon, 6 Feb 2012 09:27:06 +0100 Pawel Jakub Dawidek wrote:

 PJD> For the patch itself.

 PJD> You don't have to have two separate cases depending on request for
 PJD> pidfile. You can specify NULL pfh to the pidfile functions.
 PJD> Even in example from the manual page when pfh is NULL there is a case
 PJD> where we warn, but continue execution and call pidfile functions.
 PJD> This should simplify the code.

 PJD> If you do that (actually even if you don't), remember to either use
 PJD> warn(3) before pidfile_remove(3) and exit(3) after or preserve errno
 PJD> before calling pidfile_remove(3), as pidfile_remove(3) can modify it if
 PJD> unlink(2) is unsuccessful or pfh is NULL.

Thanks. The updated version is attached.

-- 
Mikolaj Golub


--=-=-=
Content-Type: text/x-patch
Content-Disposition: inline; filename=daemon.c.2.patch

Index: usr.sbin/daemon/daemon.c
===================================================================
--- usr.sbin/daemon/daemon.c	(revision 231014)
+++ usr.sbin/daemon/daemon.c	(working copy)
@@ -32,6 +32,7 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/param.h>
+#include <sys/wait.h>
 
 #include <err.h>
 #include <errno.h>
@@ -43,15 +44,16 @@ __FBSDID("$FreeBSD$");
 #include <unistd.h>
 
 static void restrict_process(const char *);
+static void wait_child(pid_t pid);
 static void usage(void);
 
 int
 main(int argc, char *argv[])
 {
 	struct pidfh *pfh = NULL;
-	int ch, nochdir, noclose, errcode;
+	int ch, nochdir, noclose;
 	const char *pidfile, *user;
-	pid_t otherpid;
+	pid_t otherpid, pid;
 
 	nochdir = noclose = 1;
 	pidfile = user = NULL;
@@ -79,9 +81,7 @@ main(int argc, char *argv[])
 	if (argc == 0)
 		usage();
 
-	if (user != NULL)
-		restrict_process(user);
-
+	pfh = NULL;
 	/*
 	 * Try to open the pidfile before calling daemon(3),
 	 * to be able to report the error intelligently
@@ -100,22 +100,36 @@ main(int argc, char *argv[])
 	if (daemon(nochdir, noclose) == -1)
 		err(1, NULL);
 
-	/* Now that we are the child, write out the pid */
-	if (pidfile)
+	pid = 0;
+	if (pidfile) {
+		/*
+		 * Spawn a child to exec the command, so in the parent
+		 * we could wait for it to exit and remove pidfile.
+		 */
+		pid = fork();
+		if (pid == -1) {
+			pidfile_remove(pfh);
+			err(1, "fork");
+		}
+	}
+	if (pid == 0) {
+		/* Now that we are the child, write out the pid. */
 		pidfile_write(pfh);
 
-	execvp(argv[0], argv);
+		if (user != NULL)
+			restrict_process(user);
 
-	/*
-	 * execvp() failed -- unlink pidfile if any, and
-	 * report the error
-	 */
-	errcode = errno; /* Preserve errcode -- unlink may reset it */
-	if (pidfile)
-		pidfile_remove(pfh);
+		execvp(argv[0], argv);
 
-	/* The child is now running, so the exit status doesn't matter. */
-	errc(1, errcode, "%s", argv[0]);
+		/*
+		 * execvp() failed -- report the error. The child is
+		 * now running, so the exit status doesn't matter.
+		 */
+		err(1, "%s", argv[0]);
+	}
+	wait_child(pid);
+	pidfile_remove(pfh);
+	exit(0); /* Exit status does not metter. */
 }
 
 static void
@@ -132,6 +146,19 @@ restrict_process(const char *user)
 }
 
 static void
+wait_child(pid_t pid)
+{
+	int status;
+
+	while (waitpid(pid, &status, 0) == -1) {
+		if (errno != EINTR) {
+			warn("waitpid");
+			break;
+		}
+	}
+}
+
+static void
 usage(void)
 {
 	(void)fprintf(stderr,

--=-=-=--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?86wr7zmy8f.fsf>