On Fri, Sep 13, 2013 at 04:57:28PM +0000, John-Mark Gurney wrote: > Author: jmg > Date: Fri Sep 13 16:57:28 2013 > New Revision: 255521 > URL: http://svnweb.freebsd.org/changeset/base/255521 > > Log: > add support for writing the pid of the daemon program to a pid file so > that daemon can be used w/ rc.subr and ports can use the additional > functionality, such as keeping the ldap daemon up and running, and have > the proper program to signal to exit.. > > PR: bin/181341 > Submitted by: feld > Approved by: re (glebius)
Thank you for doing this. I was aware about this issue after I had added restart option but could not come with a solution that would satisfy me. Having 2 options for pid files might look a little confusing but I think it is much better than we had before. Still please see a couple of notes below. > Modified: head/usr.sbin/daemon/daemon.c > ============================================================================== > --- head/usr.sbin/daemon/daemon.c Fri Sep 13 14:15:52 2013 > (r255520) > +++ head/usr.sbin/daemon/daemon.c Fri Sep 13 16:57:28 2013 > (r255521) > @@ -53,16 +53,17 @@ static void usage(void); > 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; > + 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) { > + ppfh = pfh = NULL; > + ppidfile = pidfile = user = NULL; > + while ((ch = getopt(argc, argv, "cfp:P:ru:")) != -1) { > switch (ch) { > case 'c': > nochdir = 0; > @@ -73,6 +74,9 @@ main(int argc, char *argv[]) > case 'p': > pidfile = optarg; > break; > + case 'P': > + ppidfile = optarg; > + break; > case 'r': > restart = 1; > break; > @@ -89,7 +93,7 @@ main(int argc, char *argv[]) > 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,6 +108,18 @@ main(int argc, char *argv[]) > err(2, "pidfile ``%s''", pidfile); > } > } > + > + /* do same for actual daemon process */ > + if (ppidfile != NULL) { > + ppfh = pidfile_open(ppidfile, 0600, &otherpid); > + if (ppfh == NULL) { > + if (errno == EEXIST) { > + errx(3, "process already running, pid: %d", > + otherpid); > + } > + err(2, "ppidfile ``%s''", ppidfile); You have to pidfile_remove(pfh) before exiting not to leave the child pidfile on fs. Also pidfile_remove(ppfh) if fork() fails, and there are several other places where pidfile_remove() is missed for the child too before err exit (me should be blamed for most of these). > + } > + } > > if (daemon(nochdir, noclose) == -1) > err(1, NULL); > @@ -176,12 +192,17 @@ restart: > */ > err(1, "%s", argv[0]); > } > + /* write out parent pidfile if needed */ > + if (ppidfile != NULL) > + pidfile_write(ppfh); > + No need to check for ppidfile != NULL. It is safe to call pidfile_write() (and pidfile_remove()) with NULL argument. Also, doing pidfile_write() here will cause needlessly rewriting the file after every child restart. I think it is better to call pidfile_write(ppfh) once, before the restart loop, just after daemon(). > setproctitle("%s[%d]", argv[0], pid); > if (wait_child(pid, &mask) == 0 && restart) { > sleep(1); > goto restart; > } > pidfile_remove(pfh); > + pidfile_remove(ppfh); > exit(0); /* Exit status does not matter. */ > } > > @@ -240,7 +261,7 @@ static void > 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); > } -- Mikolaj Golub _______________________________________________ svn-src-head@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"