FIFO channel reading incorrect

I have 2 unrelated processes. The first creates a FIFO channel and writes data to it.

testcomp:

int main(int argc, char *argv[])
{
    int f1;
    char *send_buf = "Hello";
    char recv_buf[128] = {0};

    if (mkfifo("mk.fifo", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1 && errno != EEXIST)
        error(0, errno, "mkfifo() error");

    f1 = open("mk.fifo", O_RDWR);
    perror("Opening ");

    printf("Sending string '%s'...\n", send_buf);
    write(f1, send_buf, strlen(send_buf));
    perror("Writing ");

    close(f1);
    return 0;
}

The second process should read data from a previously created channel.

test2comp:

int main(int argc, char *argv[])
{
    int f2;
    char recv_buf[128] = {0};

    f2 = open("mk.fifo", O_RDONLY|O_NONBLOCK);
    perror("Opening ");

    read(f2, recv_buf, sizeof(recv_buf));
    perror("Reading ");

    printf("Received string '%s'\n", recv_buf);

    close(f2);
    return 0;
}

The problem is that the read data is empty. What could be the reason?

Console output:

enter image description here

Upvotes: 3

Views: 438

Answers (1)

Useless
Useless

Reputation: 67812

A FIFO is just a named pipe.

It has to be open at both ends at the same time for communication to occur. For example, your local man page should say something like

The kernel maintains exactly one pipe object for each FIFO special file that is opened by at least one process. The FIFO must be opened on both ends (reading and writing) before data can be passed. Normally, opening the FIFO blocks until the other end is opened also.

What you did is:

  1. create a FIFO inode
  2. open it for writing, implicitly creating a pipe associated with that inode
  3. write something into the pipe buffer even though nothing is reading from it yet
  4. close it again, destroying the pipe
  5. open a new pipe for reading, associated with the same (currently un-used) inode
  6. there's nothing in there, because it's a new pipe

Normally I would expect the writer to block when opening the fifo, until a reader is present - I'm not sure why this didn't happen. You explicitly disabled this behaviour for the reader though by setting it to non-blocking.

Upvotes: 5

Related Questions