Reputation: 645
I am trying to write two programs that will communicate via FIFOs in C. I am experimenting with FIFOs for an assignment I have.
When I know the number of messages and read them with a for loop, it prints out all the messages that were sent from the other side. If I use a while loop, it only sends two of them. The code is slightly changed from this question How to send a simple string between two programs using pipes?
This works:
/* writer */
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
int main()
{
int fd;
char * myfifo = "/tmp/myfifo";
/* create the FIFO (named pipe) */
/* write "Hi" to the FIFO */
fd = open(myfifo, O_WRONLY);
int i;
for(i = 0; i < 10; i++)
write(fd, "Hi", sizeof("Hi"));
close(fd);
return 0;
}
And: (edited)
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#define MAX_BUF 1024
int main()
{
int fd;
char * myfifo = "/tmp/myfifo";
char buf[MAX_BUF];
mkfifo(myfifo, 0666);
/* open, read, and display the message from the FIFO */
fd = open(myfifo, O_RDONLY);
int i;
for(i = 0; i < 10; i++)
{
int n = read(fd, buf, MAX_BUF);
printf("n = %d , Received: %s\n",n, buf);
}
close(fd);
/* remove the FIFO */
unlink(myfifo);
return 0;
}
Edit: This now prints
n = 18 , Received: Hi
n = 12 , Received: Hi
n = 0 , Received: Hi
n = 0 , Received: Hi
n = 0 , Received: Hi
n = 0 , Received: Hi
n = 0 , Received: Hi
n = 0 , Received: Hi
n = 0 , Received: Hi
n = 0 , Received: Hi
When I change the reader to this, it doesn't work:
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#define MAX_BUF 1024
int main()
{
int fd;
char * myfifo = "/tmp/myfifo";
char buf[MAX_BUF];
mkfifo(myfifo, 0666);
/* open, read, and display the message from the FIFO */
fd = open(myfifo, O_RDONLY);
int i;
while(read(fd, buf, MAX_BUF))
printf("Received: %s\n", buf);
close(fd);
/* remove the FIFO */
unlink(myfifo);
return 0;
}
I am running the two programs in two separate terminals and all. When I run them with the second reader, it only prints out:
Received: Hi
Received: Hi
Any help would be appreciated.
Upvotes: 0
Views: 511
Reputation: 223699
Pipes are stream based, not message based. While the number of bytes read should match the number written, the number of read
calls is not necessarily the same as the number of write
calls.
If we modify the reader to print the number of bytes received:
int len;
while((len=read(fd, buf, MAX_BUF)) > 0) {
printf("Received %d: %s\n", len, buf);
}
I get the following output:
Received 30: Hi
So in the second case, there are 10 writes of 3 bytes (2 for the letters H
and i
and one for the null terminating byte) and 1 read of 30 bytes. The reason 3 bytes is being written on each write
call is because the string constant "Hi"
has type char [3]
.
You only see one instance of "Hi" printed because the third byte is a null byte which terminates the string, so nothing past that is printed.
Upvotes: 2
Reputation: 5311
In the second version, continued execution of the loop depends on the value returned by read()
, whereas in the first version it loops ten times unconditionally.
And since it doesn't clear the buffer, as long as the first iteration reads 'Hi', all subsequent iterations will print 'Hi' regardless of the success, partial success, or failure of the read()
.
Upvotes: 1