views:

90

answers:

2

Hi, I've to read program log file and to do that I wanted to use select() and read()

#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/select.h>
#include <fcntl.h>
#include <stdio.h>


int main()
{
    int fd = -1;
    fd_set fds;
    struct timeval tv;
    int rc; 
    char buffer[4096];
    char * log_path = "/home/mich/a.txt";
    if((fd = open(log_path,O_RDONLY) ) == -1 )
    {
        printf("error\n");
            return -1;
    }

    while(1)
    {

        FD_ZERO(&fds);
        FD_SET(fd,&fds); 
        tv.tv_sec = 2;
        tv.tv_usec = 0;
        rc = select(fd+1, &fds, NULL, NULL, &tv);

            if (rc < 0) {
                printf("failed\n");
                continue;
            } else if (rc > 0 && FD_ISSET(fd,&fds)) {
                printf("read\n");
            } else  {
                printf("timeout\n");
                continue;
            }
        while ((my_getline(buffer,sizeof(buffer),fd)) > 0)  
        {
            printf("%s",buffer);
        }   
    }
    close(fd);
}

my_getline is a function which uses read().

Output:

read
aaa
read
read
read
read
read
bbb
read
read
read
read
...

where aaa and bbb are lines from read file.

What is wrong in this program?

+3  A: 

select() tells you that a read() won't block.

That includes the case where it will return 0 to indicate end-of-file, which presumably is what you're getting.

caf
+2  A: 

select tells you that there is something waiting on fd. This doesn't have to be a line, it could be a single byte, or the information that the end of the file has been reached. Add puts("####"); at the end of the outer while loop to see how your code processes the input file.

To see how to keep reading a file that other processes are appending to, look at the source code for one of the free implementations of the unix tail utility (specifically its -f option). The traditional implementation is to read the whole file, sleep for a small interval (1 second in tail), and repeat from the position where you left off after the last read. A more modern, more reactive, less resource-consuming, but less portable approach uses a file change notification API (inotify under Linux, kqueue under *BSD, ...).

Gilles