c - Is closing a pipe necessary when followed by execlp()? -
before stating question, have read several related questions on stack overflow, such pipe & dup functions in unix, , several others,but didn't clarify confusion.
first, code, example code 'beginning linux programming', 4th edition, chapter 13:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> int main() { int data_processed; int file_pipes[2]; const char some_data[] = "123"; pid_t fork_result; if (pipe(file_pipes) == 0) { fork_result = fork(); if (fork_result == (pid_t)-1) { fprintf(stderr, "fork failure"); exit(exit_failure); } if (fork_result == (pid_t)0) // child process { close(0); dup(file_pipes[0]); close(file_pipes[0]); // line close(file_pipes[1]); // line b execlp("od", "od", "-c", (char *)0); exit(exit_failure); } else // parent process { close(file_pipes[0]); // line c data_processed = write(file_pipes[1], some_data, strlen(some_data)); close(file_pipes[1]); // line d printf("%d - wrote %d bytes\n", (int)getpid(), data_processed); } } exit(exit_success); }
the execution result is:
momo@xue5:~/testcode/ipc_pipe$ ./a.out
10187 - wrote 3 bytes
momo@xue5:~/testcode/ipc_pipe$ 0000000 1 2 3
0000003
momo@xue5:~/testcode/ipc_pipe$
if commented line a, line c, , line d, result same above. understand result, child data parent through own stdin connected pipe, , send 'od -c' result stdout.
however, if commented line b, result be:
momo@xue5:~/testcode/ipc_pipe$ ./a.out
10436 - wrote 3 bytes
momo@xue5:~/testcode/ipc_pipe$
no 'od -c' result! 'od -c' started execlp() not excuted, or output not directed stdout? 1 possibility read() of 'od' blocked, because write file descriptor file_pipes[1] of child open if commented line b. commenting line d, let write file descriptor file_pipes[1] of parent open, can still have 'od -c' output.
and, why need close pipe before execlp()? execlp() replace process image, including stack, .data, .heap, .text new image 'od'. mean, if don't close file_pipes[0] , file_pipes[1] in child line , b, file_pipes[0] , file_pipes[1] still 'destroyed' execlp()? result code, not. wrong?
thanks time , efforts here~~
is closing pipe necessary when followed execlp()?
it's not strictly necessary because depends on how pipe used. in general, yes should closed if pipe
end not needed process.
why need close pipe before execlp()? execlp() replace process image
because file descriptors (by default) remain open across exec
calls. man page: "by default, file descriptors remain open across execve(). file descriptors marked close-on-exec closed; see description of fd_cloexec in fcntl(2)."
however, if commented line b,...no 'od -c' result!
this because od
process reads stdin
until gets eof
. if process not close file_pipes[1]
not see eof
write end of pipe not closed processes had opened.
if commented line a, line c, , line d, result same above
this because file descriptors @ , c read ends of pipe , no 1 blocked waiting closed (as described above). file descriptor @ d write end , not closing indeed cause problems. however, though code not explicitly call close
on file descriptor, still closed because process exits.