diff --git a/usr.sbin/daemon/daemon.c b/usr.sbin/daemon/daemon.c --- a/usr.sbin/daemon/daemon.c +++ b/usr.sbin/daemon/daemon.c @@ -114,6 +114,8 @@ static bool daemon_is_child_dead(struct daemon_state *); static void daemon_set_child_pipe(struct daemon_state *); +static int pidfile_truncate(struct pidfh *); + static const char shortopts[] = "+cfHSp:P:ru:o:s:l:t:m:R:T:C:h"; static const struct option longopts[] = { @@ -526,6 +528,15 @@ close(kq); close(state->pipe_rd); state->pipe_rd = -1; + + /* + * We don't have to truncate the pidfile, but it's easier to test + * daemon(8) behavior in some respects if we do. We won't bother if + * the child won't be restarted. + */ + if (state->child_pidfh != NULL && state->restart_enabled) { + pidfile_truncate(state->child_pidfh); + } } static void @@ -823,3 +834,22 @@ /* The child gets dup'd pipes. */ close(state->pipe_rd); } + +static int +pidfile_truncate(struct pidfh *pfh) +{ + int pfd = pidfile_fileno(pfh); + + assert(pfd >= 0); + + if (ftruncate(pfd, 0) == -1) + return (-1); + + /* + * pidfile_write(3) will always pwrite(..., 0) today, but let's assume + * it may not always and do a best-effort reset of the position just to + * set a good example. + */ + (void)lseek(pfd, 0, SEEK_SET); + return (0); +} diff --git a/usr.sbin/daemon/tests/daemon_test.sh b/usr.sbin/daemon/tests/daemon_test.sh --- a/usr.sbin/daemon/tests/daemon_test.sh +++ b/usr.sbin/daemon/tests/daemon_test.sh @@ -139,8 +139,11 @@ kill $orig_sleep_pid # Wait up to 10s for the daemon to restart the child. for t in `seq 0 0.1 10`; do - new_sleep_pid=`cat sleep.pid` - [ "$orig_sleep_pid" -ne "$new_sleep_pid" ] && break + if [ -s "sleep.pid" ]; then + new_sleep_pid=`cat sleep.pid` + [ "$orig_sleep_pid" -ne "$new_sleep_pid" ] && break + fi + sleep 0.1 done [ "$orig_sleep_pid" -ne "$new_sleep_pid" ] || \