start-stop-daemon: use a pipe to sync parent/child processes

This fixes #557.
This commit is contained in:
Mike Gilbert 2022-10-29 12:38:43 -04:00 committed by William Hubbs
parent 953172c6c6
commit 1364e6631c

View File

@ -354,6 +354,9 @@ int main(int argc, char **argv)
#ifdef PR_SET_NO_NEW_PRIVS #ifdef PR_SET_NO_NEW_PRIVS
bool no_new_privs = false; bool no_new_privs = false;
#endif #endif
int pipefd[2];
char readbuf[1];
ssize_t ss;
applet = basename_c(argv[0]); applet = basename_c(argv[0]);
atexit(cleanup); atexit(cleanup);
@ -864,12 +867,17 @@ int main(int argc, char **argv)
if (background) if (background)
signal_setup(SIGCHLD, handle_signal); signal_setup(SIGCHLD, handle_signal);
/* Use a pipe to sync the parent/child processes. */
if (pipe2(pipefd, O_CLOEXEC) == -1)
eerrorx("%s: pipe2: %s", applet, strerror(errno));
if ((pid = fork()) == -1) if ((pid = fork()) == -1)
eerrorx("%s: fork: %s", applet, strerror(errno)); eerrorx("%s: fork: %s", applet, strerror(errno));
/* Child process - lets go! */ /* Child process - lets go! */
if (pid == 0) { if (pid == 0) {
pid_t mypid = getpid(); pid_t mypid = getpid();
close(pipefd[0]); /* Close the read end of the pipe. */
umask(numask); umask(numask);
#ifdef TIOCNOTTY #ifdef TIOCNOTTY
@ -1097,6 +1105,7 @@ int main(int argc, char **argv)
dup2(stderr_fd, STDERR_FILENO); dup2(stderr_fd, STDERR_FILENO);
for (i = getdtablesize() - 1; i >= 3; --i) for (i = getdtablesize() - 1; i >= 3; --i)
if (i != pipefd[1])
close(i); close(i);
if (scheduler != NULL) { if (scheduler != NULL) {
@ -1140,6 +1149,18 @@ int main(int argc, char **argv)
} }
/* Parent process */ /* Parent process */
close(pipefd[1]); /* Close the write end of the pipe. */
/* The child never writes to the pipe, so this read will block until
* the child calls exec or exits. */
while ((ss = read(pipefd[0], readbuf, 1)) == -1 && errno == EINTR);
if (ss == -1)
eerrorx("%s: failed to read from pipe: %s",
applet, strerror(errno));
close(pipefd[0]);
if (!background) { if (!background) {
/* As we're not backgrounding the process, wait for our pid /* As we're not backgrounding the process, wait for our pid
* to return */ * to return */