daemon: flatten and simplify fork() logic

Reviewed by:	kevans
Pull Request:	https://github.com/freebsd/freebsd-src/pull/672
This commit is contained in:
Ihor Antonov 2023-03-02 23:17:02 -06:00 committed by Kyle Evans
parent 39ea4280e4
commit 75f61ca920

View File

@ -84,7 +84,7 @@ static void daemon_sleep(time_t, long);
static volatile sig_atomic_t terminate = 0; static volatile sig_atomic_t terminate = 0;
static volatile sig_atomic_t child_gone = 0; static volatile sig_atomic_t child_gone = 0;
static volatile sig_atomic_t pid = -1; static volatile sig_atomic_t pid = 0;
static volatile sig_atomic_t do_log_reopen = 0; static volatile sig_atomic_t do_log_reopen = 0;
static const char shortopts[] = "+cfHSp:P:ru:o:s:l:t:m:R:T:h"; static const char shortopts[] = "+cfHSp:P:ru:o:s:l:t:m:R:T:h";
@ -368,34 +368,27 @@ main(int argc, char *argv[])
*/ */
child_gone = 0; child_gone = 0;
pid = fork(); pid = fork();
if (pid == -1) {
warn("fork");
goto exit;
} else if (pid > 0) {
/*
* Unblock SIGTERM after we know we have a valid
* child PID to signal.
*/
if (sigprocmask(SIG_UNBLOCK, &mask_term, NULL)) {
warn("sigprocmask");
goto exit;
}
close(pfd[1]);
pfd[1] = -1;
}
} }
if (pid <= 0) {
/* Now that we are the child, write out the pid. */ /* fork failed, this can only happen when supervision is enabled */
if (pid == -1) {
warn("fork");
goto exit;
}
/* fork succeeded, this is child's branch or supervision is disabled */
if (pid == 0) {
pidfile_write(child_pidfh); pidfile_write(child_pidfh);
if (user != NULL) { if (user != NULL) {
restrict_process(user); restrict_process(user);
} }
/* /*
* When forking, the child gets the original sigmask, * In supervision mode, the child gets the original sigmask,
* and dup'd pipes. * and dup'd pipes.
*/ */
if (pid == 0) { if (supervision_enabled) {
close(pfd[0]); close(pfd[0]);
if (sigprocmask(SIG_SETMASK, &mask_orig, NULL)) { if (sigprocmask(SIG_SETMASK, &mask_orig, NULL)) {
err(1, "sigprogmask"); err(1, "sigprogmask");
@ -416,12 +409,24 @@ main(int argc, char *argv[])
} }
} }
execvp(argv[0], argv); execvp(argv[0], argv);
/* /* execvp() failed - report error and exit this process */
* execvp() failed -- report the error. The child is
* now running, so the exit status doesn't matter.
*/
err(1, "%s", argv[0]); err(1, "%s", argv[0]);
} }
/*
* else: pid > 0
* fork succeeded, this is the parent branch, this can only happen when
* supervision is enabled
*
* Unblock SIGTERM after we know we have a valid child PID to signal.
*/
if (sigprocmask(SIG_UNBLOCK, &mask_term, NULL)) {
warn("sigprocmask");
goto exit;
}
close(pfd[1]);
pfd[1] = -1;
setproctitle("%s[%d]", title, (int)pid); setproctitle("%s[%d]", title, (int)pid);
/* /*
* As we have closed the write end of pipe for parent process, * As we have closed the write end of pipe for parent process,