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
This commit is contained in:
Poul-Henning Kamp 2004-06-02 06:48:13 +00:00
parent dc03363dd8
commit 846be7bd0e
2 changed files with 46 additions and 6 deletions

View File

@ -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

View File

@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@ -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);
}