I want to make a pipe between a child-writer and a parent-reader in C. I thought that my parent process would have to wait for its child to write in the buffer before being able to read it, but then I wanted to check it so I wrote the following piece of code:
pipe(fd);
// ... checks for pipe
pid_t pid = fork();
// ... checks for fork
if (pid == 0) {
close(fd[0]);
// Long sleep hoping parent will terminate before the write()
sleep(10);
write(fd[1], "hello", strlen("hello") + 1);
close(fd[1]);
} else {
close(fd[1]);
read(fd[0], buf, sizeof(buf));
printf("received: %s\n", buf);
close(fd[0]);
}
return 0;
The output is unexpectedly (or is it not?) received: hello
.
Same output if I replace the call to sleep() by a for (volatile int i = 0; i < some_big_int; ++i);
loop.
I do not think that the call to read()
will block my parent process until child writes at the other end of the pipe, but I cannot explain this behaviour though. Any hint?
read
will block until there is at least one byte to read, or it encounters an error, or it reaches the end of the stream. When there is at least one byte to read, it will read as many bytes as it can (up to the maximum number you specify) and then return.
In this case, the parent process's call to read
will block until the child process write
s something to the pipe.
From man 7 pipe
section I/O on pipes and FIFOs :
If a process attempts to read from an empty pipe, then read(2) will block until data is available. If a process attempts to write to a full pipe (see below), then write(2) blocks until sufficient data has been read from the pipe to allow the write to complete. Nonblocking I/O is possible by using the fcntl(2) F_SETFL operation to enable the O_NONBLOCK open file status flag.