Behavior of Pipe C

296 views Asked by At

I have this code:

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <signal.h>
#define READ 0
#define WRITE 1

char* phrase = "Hello";

void PIPE(){

    int fd [2], bytesRead;
    char message [100]; /* Parent process' message buffer */
    pipe (fd); /*Create an unnamed pipe */

    if (fork () == 0) /* Child, writer */
    {
        close(fd[READ]); /* Close unused end */
        write (fd[WRITE],phrase, strlen (phrase) + 1); 
        close (fd[WRITE]); /* Close used end*/
    }
    else /* Parent, reader*/
    {
        close (fd[WRITE]); /* Close unused end */
        bytesRead = read (fd[READ], message, 100);
        printf ("Read %d bytes: %s\n", bytesRead, message); /* Send */
        close (fd[READ]); /* Close used end */
    }
}

I'm studying the Pipe in C , and my book says:

If a process reads from a pipe whose write end has been closed, the read () returns a 0, indicating end-of-input.

but in the code(in the parent part) , before read function the write part has close and the read function doesn't return 0 but 5(lenght of Hello).

what is wrong?

thank for your time

UPDATE 1:

I have another question for you(I understand the first problem ):

at the beginning if the reader reads empty pipe, the read function returns 0, but how can I be sure this is the first writer to start and then after the reader ?

3

There are 3 answers

1
too honest for this site On

It should include "once all written data has been read". Otherwise a pipe would not make much sense. Or would require to explicitly signal to the writer the reader has taken all data from the pipe before closing - breaking its file semantics.

1
Jean-Baptiste Yunès On

This is true for empty pipe as POSIX says:

When attempting to read from an empty pipe or FIFO:

If no process has the pipe open for writing, read() shall return 0 to indicate end-of-file

Answer update 1:

Pipes (in normal blocking mode) provide synchronization at both ends : reader is blocked while pipe is empty, and writer is blocked while pipe is full.

You have no need to ensure writer writes before reader reads or something like that. If the reader tries to read an empty pipe it will be blocked until : either someone else writes in the pipe or the last writer closes its end.

4
Philipp Murry On

First of all, you dont know whether the pipe was closed when the parent reads from it. Since there are two proccesses involved, the scheduler decides which process runs next and for how long - not the order of your code.

Secondly, as already said, the string written to the pipe is still in it's buffer. Thus, the parent will read everything that's in the buffer before it returns EOF.