Let's consider a common scenario
Create a pipe and fork (assuming no error happens)
pipe (pipefd); fork();A parent process writes to pipe, closes it and waits for its child
write(pipefd[1], str, strlen(str); close(pipefd[1]); wait(NULL);The child process reads from pipe until EOF
while ((len = read(pipefd[0], buf, BUF_SIZE)) > 0) write(STDOUT_FILENO, &buf, len); close(pipefd[0]); exit(len == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
Calling close(pipefd[1]) on parent can potentially fail with an error due to some reasons. What will happen on the child's end in this case? Should child also receive read error or can remain blocked on the read call? Can this code lead to a dead lock (child on read, parent on wait) in this case? What is a correct way to handle this situation?
As a preliminary matter, you do not describe the child process closing
pipefd[1]. All else notwithstanding, the child must do that before it can expect itsread(pipefd[0])calls ever to report an EOF condition.Yes, in general, and in the sense that
close()may return -1 and seterrno. But that does not necessarily imply that the file descriptor was not closed. This is a tricky situation. You should read the NOTES section of the close(2) manual page for a discussion, which is too long to reproduce here.It depends. There is no answer at the level of generality at which the question is posed.
On some systems, such as Linux,
close()always closes the specified file descriptor, provided that it is initially a valid, open file descriptor, even in cases where it ultimately reports an error. On such systems, it is likely, but not guaranteed, that the child'sread()would not, then, block indefinitely.If the parent ignores a failure to
close()the write end of the pipe? Yes, the child continuing to block onread()is within the possibilities allowed by POSIX. If the parent then proceeds towait()ing on the child then that could deadlock.If
close()fails then the parent should report an error in some way -- diagnostic message, exiting with a failure status, or returning an error code, for example. It could consider also trying to force the child to terminate by, for example, sending it aSIGTERMor even aSIGKILL. Even without killing the child, you have to assume in this case that there may have been data loss or corruption, so killing the child does not make you any worse off in that regard.