Refactored nxt_process_create() for more explicit pipe closing.

This commit is contained in:
Valentin Bartenev
2019-09-26 16:03:02 +03:00
parent 9c06bfdf2c
commit f2c0f2899a

View File

@@ -42,7 +42,8 @@ nxt_bool_t nxt_proc_remove_notify_matrix[NXT_PROCESS_MAX][NXT_PROCESS_MAX] = {
static nxt_int_t
nxt_process_worker_setup(nxt_task_t *task, nxt_process_t *process, int parentfd) {
nxt_process_worker_setup(nxt_task_t *task, nxt_process_t *process, int parentfd)
{
pid_t rpid, pid;
ssize_t n;
nxt_int_t parent_status;
@@ -87,11 +88,6 @@ nxt_process_worker_setup(nxt_task_t *task, nxt_process_t *process, int parentfd)
return NXT_ERROR;
}
if (nxt_slow_path(close(parentfd) == -1)) {
nxt_alert(task, "failed to close reader pipe fd");
return NXT_ERROR;
}
if (nxt_slow_path(parent_status != NXT_OK)) {
return parent_status;
}
@@ -153,36 +149,25 @@ nxt_process_create(nxt_task_t *task, nxt_process_t *process)
#if (NXT_HAVE_CLONE)
pid = nxt_clone(SIGCHLD | init->isolation.clone.flags);
#else
pid = fork();
#endif
if (nxt_slow_path(pid < 0)) {
#if (NXT_HAVE_CLONE)
nxt_alert(task, "clone() failed while creating \"%s\" %E",
init->name, nxt_errno);
goto cleanup;
}
#else
pid = fork();
if (nxt_slow_path(pid < 0)) {
nxt_alert(task, "fork() failed while creating \"%s\" %E",
init->name, nxt_errno);
goto cleanup;
}
#endif
if (nxt_slow_path(close(pipefd[0]) != 0)) {
nxt_alert(task, "failed to close pipe: %E", nxt_errno);
}
if (nxt_slow_path(close(pipefd[1]) != 0)) {
nxt_alert(task, "failed to close pipe: %E", nxt_errno);
}
return pid;
}
if (pid == 0) {
/* Child. */
if (nxt_slow_path(close(pipefd[1]) == -1)) {
nxt_alert(task, "failed to close writer pipe fd");
return NXT_ERROR;
}
ret = nxt_process_worker_setup(task, process, pipefd[0]);
@@ -190,6 +175,10 @@ nxt_process_create(nxt_task_t *task, nxt_process_t *process)
exit(1);
}
if (nxt_slow_path(close(pipefd[0]) == -1)) {
nxt_alert(task, "failed to close writer pipe fd");
}
/*
* Explicitly return 0 to notice the caller function this is the child.
* The caller must return to the event engine work queue loop.
@@ -199,10 +188,6 @@ nxt_process_create(nxt_task_t *task, nxt_process_t *process)
/* Parent. */
if (nxt_slow_path(close(pipefd[0]) != 0)) {
nxt_alert(task, "failed to close pipe: %E", nxt_errno);
}
/*
* At this point, the child process is blocked reading the
* pipe fd to get its real pid (rpid).
@@ -219,14 +204,14 @@ nxt_process_create(nxt_task_t *task, nxt_process_t *process)
if (nxt_slow_path(write(pipefd[1], &pid, sizeof(pid)) == -1)) {
nxt_alert(task, "failed to write real pid");
goto fail_cleanup;
goto fail;
}
#if (NXT_HAVE_CLONE_NEWUSER)
if ((init->isolation.clone.flags & CLONE_NEWUSER) == CLONE_NEWUSER) {
ret = nxt_clone_proc_map(task, pid, &init->isolation.clone);
if (nxt_slow_path(ret != NXT_OK)) {
goto fail_cleanup;
goto fail;
}
}
#endif
@@ -235,20 +220,16 @@ nxt_process_create(nxt_task_t *task, nxt_process_t *process)
if (nxt_slow_path(write(pipefd[1], &ret, sizeof(ret)) == -1)) {
nxt_alert(task, "failed to write status");
goto fail_cleanup;
}
if (nxt_slow_path(close(pipefd[1]) != 0)) {
nxt_alert(task, "failed to close pipe: %E", nxt_errno);
goto fail;
}
process->pid = pid;
nxt_runtime_process_add(task, process);
return pid;
goto cleanup;
fail_cleanup:
fail:
ret = NXT_ERROR;
@@ -256,13 +237,21 @@ fail_cleanup:
nxt_alert(task, "failed to write status");
}
waitpid(pid, NULL, 0);
pid = -1;
cleanup:
if (nxt_slow_path(close(pipefd[0]) != 0)) {
nxt_alert(task, "failed to close pipe: %E", nxt_errno);
}
if (nxt_slow_path(close(pipefd[1]) != 0)) {
nxt_alert(task, "failed to close pipe: %E", nxt_errno);
}
waitpid(pid, NULL, 0);
return -1;
return pid;
}