Reputation: 565
I'm reading from a pipe.
char buf[255];
while((nbytes = read(fd,buf,sizeof(buf)) > 0)) // fd is the opened pipe
{
if(strcmp(buf,"IN")==0){
printf("%s\n", "SET IN");
}
if(strcmp(buf,"OUT")==0){
printf("%s\n", "SET OUT");
}
}
Now when I write to the pipe via terminal
echo "OUT" > /path/to/FIFO
the output I'm getting is: "SET IN"
All the things I type I always get "SET IN" as the output. How can I compare it the string I read from the pipe?
Upvotes: 1
Views: 1429
Reputation: 399949
You are treating the read data as a string (by passing it to strcmp()
), but there is no guarantee that the input data is 0-terminated. In particular, read()
doesn't 0-terminate the data, it will fill the entire buffer with data if possible.
You need to do it yourself, by modifying the read call to something like:
while((nbytes = read(fd, buf, sizeof buf - 1)) > 0 ) // fd is the opened pipe
{
buf[nbytes - 1] = '\0';
Note that the size passed to read()
has shrunk to make space for the terminator, and that we add it.
Also note that I corrected the parentheses in the while
, as mentioned in a comment by @AhmedMasud above. That's a good point, I forgot to emphasize it.
UPDATE: As mentioned by xaxxon's answer, the data will be delivered in unpredictable chunks, so a protocol might be useful. The easiest protocol for textual data flowing over a pipe is (of course?) line-based. This would mean that you should collect data until you detect an end-of-line character. When you do, parse the contents of the buffer, then clear it.
Upvotes: 1
Reputation: 19771
As unwind pointed out, you cannot treat data straight off the pipe as string data and expect things to go well.
What you really need to do is define a protocol for your data transmission and write something that can send and receive that protocol.
It doesn't have to be complex, though.
For example, you might do something where the first 4 bytes represents the length of the data you are sending, followed by the data. When you've read 4 bytes + the value of those first 4 bytes worth of data, then you would do a comparison against that data vs a known set of expected values. If you wanted to use string comparison functions, part of that data might contain the null terminator. You could also choose to use memcmp() to perform the test, as well, without null termination.
There are tons of different ways to send data, and while this may feel like overkill, you have to be careful in not assuming that when you make a single call to read that you'll always get all the data you are expecting. In the example above, you would keep calling it until you get the expected amount of data, likely buffering it until you had everything, and then checking to see what it was.
Upvotes: 1