How to avoid read() from hanging in the following situation?

邮差的信 提交于 2019-12-24 05:26:15

问题


I have some code that forks a third-party application and redirects its standard output to the parent process, roughly as follows (no error handling here for brevity):

char* args[] = {"/path/to/3rd/party/binary", "with", "args", NULL};

int fds[2];
pipe2(fds, O_CLOEXEC);

pid_t pid = fork();
if (pid == 0)
{
    dup2(fds[1], STDOUT_FILENO);
    execvp(args[0], args);
    _exit(1);
}
else
{
    close(fds[1]);

    char buf[1024];
    int bytes_read;
    while ((bytes_read = read(fds[0], buf, sizeof buf - 1)) > 0)
    {
        buf[bytes_read] = '\0';
        printf("%s", buf);
    }

    close(fds[0]);
    waitpid(pid, NULL, 0);
}

I have no code for the third-party application, it is a proprietary binary. When running the third-party application in a terminal with the same arguments as used in the code above, it eventually finishes. However, when forking the third-party binary using the code above, it does not finish, but becomes a zombie process, and the code above hangs on the read() call.

The third-party binary that is forked itself forks two daemon processes (again, proprietary binaries I do not control), which I think is causing the problem here. The forked daemon processes will have a copy of the duplicated file descriptor, preventing the read() from finishing. Indeed, in case the dup2() call is replaced with:

dup3(fds[1], STDOUT_FILENO, O_CLOEXEC);

the child process finishes, but there is no output redirection to the parent process of course. Also, when the code above is modified to not do any output redirection to the parent over a pipe, the child process finishes correctly.

Is it possible to somehow prevent this hang on the read() call in this situation, or do I need to resort to some form of non-blocking I/O?

Update; using a simple popen() suffers from the same problem.

(Follow-up from: read() hangs on zombie process)


回答1:


You need to specifically ignore SIGCHLD. It's your responsibility to reap the zombie, but you can't do it when blocked in read. If you call read after the SIGCHLD has been swallowed, you'll stay in read forever.



来源:https://stackoverflow.com/questions/53562111/how-to-avoid-read-from-hanging-in-the-following-situation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!