diff options
| -rw-r--r-- | src/start-stop-daemon/start-stop-daemon.c | 23 | 
1 files changed, 22 insertions, 1 deletions
| diff --git a/src/start-stop-daemon/start-stop-daemon.c b/src/start-stop-daemon/start-stop-daemon.c index e439388f..d3f6fd4d 100644 --- a/src/start-stop-daemon/start-stop-daemon.c +++ b/src/start-stop-daemon/start-stop-daemon.c @@ -354,6 +354,9 @@ int main(int argc, char **argv)  #ifdef PR_SET_NO_NEW_PRIVS  	bool no_new_privs = false;  #endif +	int pipefd[2]; +	char readbuf[1]; +	ssize_t ss;  	applet = basename_c(argv[0]);  	atexit(cleanup); @@ -864,12 +867,17 @@ int main(int argc, char **argv)  	if (background)  		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)  		eerrorx("%s: fork: %s", applet, strerror(errno));  	/* Child process - lets go! */  	if (pid == 0) {  		pid_t mypid = getpid(); +		close(pipefd[0]); /* Close the read end of the pipe. */  		umask(numask);  #ifdef TIOCNOTTY @@ -1097,7 +1105,8 @@ int main(int argc, char **argv)  			dup2(stderr_fd, STDERR_FILENO);  		for (i = getdtablesize() - 1; i >= 3; --i) -			close(i); +			if (i != pipefd[1]) +				close(i);  		if (scheduler != NULL) {  			int scheduler_index; @@ -1140,6 +1149,18 @@ int main(int argc, char **argv)  	}  	/* 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) {  		/* As we're not backgrounding the process, wait for our pid  		 * to return */ | 
