clinuxnamed-pipesfifoposix-select

Continuous reading of FIFO using select()


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?


Solution

  • 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.