Sync daemon(8) with FreeBSD:
authorLiam J. Foy <liamfoy@dragonflybsd.org>
Tue, 21 Dec 2004 23:30:57 +0000 (23:30 +0000)
committerLiam J. Foy <liamfoy@dragonflybsd.org>
Tue, 21 Dec 2004 23:30:57 +0000 (23:30 +0000)
- Give daemon(8) the ability to create a pid-file. Since the
  target program does not know anything about the pid-file and
  we don't keep a babysitting process for the task, the pid-file
  will linger.
- Add some small modifications to the sync'd code.
- Add WARNS?= 6 and make it WARNS 6 clean.

Ok'ed by: Joerg

usr.sbin/daemon/Makefile
usr.sbin/daemon/daemon.8
usr.sbin/daemon/daemon.c

index dac48d9..1f54ea2 100644 (file)
@@ -1,8 +1,8 @@
 # $FreeBSD: src/usr.sbin/daemon/Makefile,v 1.1.2.1 2002/08/28 17:25:54 sheldonh Exp $
-# $DragonFly: src/usr.sbin/daemon/Makefile,v 1.2 2003/06/17 04:29:53 dillon Exp $
+# $DragonFly: src/usr.sbin/daemon/Makefile,v 1.3 2004/12/21 23:30:57 liamfoy Exp $
 
 PROG=  daemon
-WARNS?=        2
+WARNS?=        6       
 MAN=   daemon.8
 
 .include <bsd.prog.mk>
index f3b0daf..59a295f 100644 (file)
@@ -25,7 +25,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\" $FreeBSD: src/usr.sbin/daemon/daemon.8,v 1.2.2.2 2003/02/05 03:30:32 trhodes Exp $
-.\" $DragonFly: src/usr.sbin/daemon/daemon.8,v 1.2 2003/06/17 04:29:53 dillon Exp $
+.\" $DragonFly: src/usr.sbin/daemon/daemon.8,v 1.3 2004/12/21 23:30:57 liamfoy Exp $
 .\"
 .Dd August 30, 2001
 .Dt DAEMON 8
@@ -36,6 +36,7 @@
 .Sh SYNOPSIS
 .Nm
 .Op Fl cf
+.Op Fl p Ar pidfile
 .Ar command arguments ...
 .Sh DESCRIPTION
 The
@@ -51,13 +52,20 @@ Change the current working directory to the root
 .It Fl f
 Redirect standard input, standard output and standard error to
 .Pa /dev/null .
+.It Fl p Ar file
+Write the ID of the created process into the
+.Ar file .
+Note, that the file will be created shortly before the process is
+actually executed, and will remain after the process exits (although
+it will be removed if the execution fails).
 .El
 .Sh DIAGNOSTICS
 The
 .Nm
 utility exits 1 if an error is returned by the
 .Xr daemon 3
-library routine, otherwise 0.
+library routine, 2 if the pid-file is requested, but can not be opened,
+otherwise it will return 0.
 If the command cannot be executed, an error message is displayed on
 standard error unless the
 .Fl f
index 4ab34ef..647a7dd 100644 (file)
  *
  *     From BSDI: daemon.c,v 1.2 1996/08/15 01:11:09 jch Exp
  * $FreeBSD: src/usr.sbin/daemon/daemon.c,v 1.1.2.1 2002/08/28 17:25:54 sheldonh Exp $
- * $DragonFly: src/usr.sbin/daemon/daemon.c,v 1.3 2004/12/18 22:48:03 swildner Exp $
+ * $DragonFly: src/usr.sbin/daemon/daemon.c,v 1.4 2004/12/21 23:30:57 liamfoy Exp $
  */
 
 #include <sys/types.h>
 
 #include <err.h>
+#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
@@ -42,10 +43,14 @@ static void usage(void);
 int
 main(int argc, char *argv[])
 {
-       int ch, nochdir, noclose;
+       int ch, nochdir, noclose, errcode;
+       FILE *pidf;
+       const char *pidfile;
 
        nochdir = noclose = 1;
-       while ((ch = getopt(argc, argv, "-cf")) != -1) {
+       pidfile = NULL;
+       pidf = 0;
+       while ((ch = getopt(argc, argv, "cfp:")) != -1) {
                switch (ch) {
                case 'c':
                        nochdir = 0;
@@ -53,6 +58,8 @@ main(int argc, char *argv[])
                case 'f':
                        noclose = 0;
                        break;
+               case 'p':
+                       pidfile = optarg;
                case '?':
                default:
                        usage();
@@ -63,17 +70,43 @@ main(int argc, char *argv[])
 
        if (argc == 0)
                usage();
+
+       /*
+        * Try to open the pidfile before calling daemon(3),
+        * to be able to report the error intelligently
+        */
+       if (pidfile) {
+               pidf = fopen(pidfile, "w");
+               if (pidf == NULL)
+                       err(1, "pidfile ``%s''", pidfile);
+       }
+
        if (daemon(nochdir, noclose) == -1)
-               err(1, NULL);
+               err(1, "daemon failed");
+
+       /* Now that we are the child, write out the pid */
+       if (pidfile) {
+               fprintf(pidf, "%ld\n", (long)getpid());
+               fclose(pidf);
+       }
+
        execvp(argv[0], argv);
 
+       /*
+        * execvp() failed -- unlink pidfile if any, and
+        * report the error
+        */
+       errcode = errno; /* Preserve errcode -- unlink may reset it */
+       if (pidfile)
+               unlink(pidfile);
+
        /* The child is now running, so the exit status doesn't matter. */
-       err(1, "%s", argv[0]);
+       errc(1, errcode, "%s", argv[0]);
 }
 
 static void
 usage(void)
 {
-       fprintf(stderr, "usage: daemon [-cf] command arguments ...\n");
+       fprintf(stderr, "usage: daemon [-cf] [-p pidfile] command arguments ...\n");
        exit(1);
 }