From 846be7bd0ebecc5cb13cdbf270a820d31b5a2708 Mon Sep 17 00:00:00 2001 From: Poul-Henning Kamp Date: Wed, 2 Jun 2004 06:48:13 +0000 Subject: [PATCH] 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. Submitted by: mi PR: 56398 --- usr.sbin/daemon/daemon.8 | 10 +++++++++- usr.sbin/daemon/daemon.c | 42 +++++++++++++++++++++++++++++++++++----- 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/usr.sbin/daemon/daemon.8 b/usr.sbin/daemon/daemon.8 index ec49f47e75c5..23702db9d75e 100644 --- a/usr.sbin/daemon/daemon.8 +++ b/usr.sbin/daemon/daemon.8 @@ -35,6 +35,7 @@ .Sh SYNOPSIS .Nm .Op Fl cf +.Op Fl p Ar pidfile .Ar command arguments ... .Sh DESCRIPTION The @@ -50,13 +51,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 0. If the command cannot be executed, an error message is displayed on standard error unless the .Fl f diff --git a/usr.sbin/daemon/daemon.c b/usr.sbin/daemon/daemon.c index 7676c70e1e94..b30a7f40e0b9 100644 --- a/usr.sbin/daemon/daemon.c +++ b/usr.sbin/daemon/daemon.c @@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -43,10 +44,13 @@ 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; + while ((ch = getopt(argc, argv, "-cfp:")) != -1) { switch (ch) { case 'c': nochdir = 0; @@ -54,7 +58,9 @@ main(int argc, char *argv[]) case 'f': noclose = 0; break; - case '?': + case 'p': + pidfile = optarg; + break; default: usage(); } @@ -64,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(2, "pidfile ``%s''", pidfile); + } + if (daemon(nochdir, noclose) == -1) err(1, NULL); + + /* Now that we are the child, write out the pid */ + if (pidfile) { + fprintf(pidf, "%lu\n", (unsigned 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) { - (void)fprintf(stderr, "usage: daemon [-cf] command arguments ...\n"); + (void)fprintf(stderr, + "usage: daemon [-cf] [-p pidfile] command arguments ...\n"); exit(1); }