Reputation: 11
I have an assignment to:
a) check the capacity of a named pipe (FIFO)
b) check how many bytes I need to read from a full pipe before writing again.
My code successfully writes into the pipe until it is full and says that 65536 bytes is its capacity, yet then reading fails (the value checked by the if condition is -1), and for reasons unknown to me it manages to write into a full pipe without reading anything. The error code for the read fail is 'Resource temporarily unavailable'. Below is my code with the debugging prints removed for clarity. The output of the code is 'Write successful after reading 0 bytes'.
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
int main() {
int l = 0;
int stream;
char* fifo = "/tmp/fifo";
mkfifo(fifo, 0666);
char test = 255;
int p = fork();
char readtest;
if (p > 0) { //rodzic
wait(NULL);
stream = open(fifo, O_RDWR | O_NONBLOCK);
while (1) {
if (read(stream, &readtest, 1) == 1) {
l++;
printf("Read byte %d, attempting write", l);
}
if (write(stream, &test, 1) == 1) {
printf("Write successful after reading %d bytes\n", l);
return 0;
}
}
} else if (p == 0) { //dziecko
stream = open(fifo, O_RDWR | O_NONBLOCK);
while (write(stream, &test, 1) == 1 ) {
l++;
//printf("b%d\n", l);
}
close(stream);
printf("Wrote %d bytes, pipe full\n", l);
_Exit(0);
}
Upvotes: 1
Views: 62
Reputation: 212248
In this case, the parent and child are using different pipes. Normally (not non-blocking), when you open a fifo for writing the open will not return until some other process opens the same fifo for reading. At that point, the 2 processes are sharing a pipe. Since your child is opening the fifo non-blocking, it does not wait for a reader. When the child closes the pipe, all the data that it wrote vanishes into the ether. The parent subsequently opens the fifo and gets a different pipe that has never been written to.
To get around this, you need to have the parent open the fifo before the child closes it.
Upvotes: 1