I am trying to read a FIFO in the background (using a thread) while my main program is running inside an infinite loop. I want to use select()
because otherwise the processor runs at 100%, but the appropriate example I found isn't working. This is the example code:
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/select.h>
#include <sys/stat.h>
#include <unistd.h>
int main()
{
mkfifo("FIFO", 0666);
fd_set readCheck;
fd_set errCheck;
char buffer[64];
struct timeval timeout;
int rv;
int fd = open("FIFO", O_RDONLY | O_RSYNC);
FD_ZERO(&readCheck);
FD_ZERO(&errCheck);
while (1) {
FD_SET(fd, &readCheck);
FD_SET(fd, &errCheck);
timeout.tv_sec = 1;
timeout.tv_usec = 0;
rv = select(fd, &readCheck, NULL, &errCheck, &timeout);
if (rv < 0) {
printf("Select failed\r\n");
break;
}
if (FD_ISSET(fd, &errCheck)) {
printf("FD error\r\n");
continue;
}
if (FD_ISSET(fd, &readCheck)) {
memset(buffer, 0, sizeof(buffer));
rv = read(fd, buffer, sizeof(buffer));
if (rv < 0) {
printf("Read failed\r\n");
break;
}
printf(buffer);
buffer[64] = '\0';
}
}
close(fd);
return 0;
}
When I write to the FIFO file nothing happens, but using cat FIFO
prints the contents. What can be the problem?
You have to give the first argument as one higher than the last opened file descriptor. From the man page page of select
,
nfds is the highest-numbered file descriptor in any of the three sets, plus 1
Change this line,
rv = select(fd, &readCheck, NULL, &errCheck, &timeout);
to
rv = select(fd+1, &readCheck, NULL, &errCheck, &timeout);
If you are not mentioning this,then select will not check your descriptor so you will not the file descriptor is ready for reading.