Does a read() in parent process wait for a child write() in a pipe?

12,102

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 writes 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.

Share:
12,102
hdl
Author by

hdl

True penguins can't fly.

Updated on June 07, 2022

Comments

  • hdl
    hdl almost 2 years

    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?

    • user3629249
      user3629249 over 8 years
      this is the expected operation: I.E. read() blocks, will return on total bytes requested are read or eof is encountered. Or certain error events and signals
    • hdl
      hdl over 8 years
      I cannot find where this is said in man 2 read: e.g. this sentence seems to indicate that if there is nothing to read, read() returns and is non-blocking : In the absence of any errors, or if read() does not check for errors, a read() with a count of 0 returns zero and has no other effects.
    • ShadowRanger
      ShadowRanger over 8 years
      When read is passed a non-zero count on a streaming fd (e.g. a pipe), it blocks until at least 1 byte is available, then reads as much of count as it can at that time. Since you write and close (and the write is smaller than PIPE_BUF), it's flushing the whole string at once, so when it unblocks, it gets all of what you wrote at once.
    • ShadowRanger
      ShadowRanger over 8 years
      The bit about read with a count of 0 is irrelevant to your situation, because you didn't pass a count of 0.
    • Andrew Henle
      Andrew Henle over 8 years
      write(fd[1], "hello", strlen("hello")); and read(fd[0], buf, sizeof(buf)); will not NUL-terminate buf, as the terminating NUL is not written to the pipe. Also, printf("received: %s\n", buffer); prints the output of buffer, not the contents of buf. Were it to try to print the contents of buf, the code posted would invoke undefined behavior. Additionally, a failed fork() call will result in the parent process blocking forever in read().
    • user3629249
      user3629249 over 8 years
      perhaps the answers/comments at: <stackoverflow.com/questions/32940575/…> would be helpful
  • hdl
    hdl over 8 years
    Where is this specified? Unfortunately I id not find this information in either man 2 pipe nor man 2 read
  • hdl
    hdl over 8 years
    Found it in man 7 pipe, and edited your answer accordingly. Thank you very much.