Reputation: 43
EDIT: I used, finally, inotify. As stefanB says, inotify is the thing to use. I found a tail clone that uses inotify to implement the -f mode, inotail.
Original question text:
I'm trying to implement the "tail -f" logic in a C project, for prototyping purposes I developed it in python as follow:
# A forever loop, each 5 seconds writes a line into file.txt
from time import *
while 1:
sleep(5)
file = open("file.txt", "a")
file.write("This is a test\n")
file.close()
The next code follows the eof of file.txt (updated by the code above)
# tail -f
from time import *
file = open("file.txt", "r")
file.seek(0, 2)
while 1:
line = file.readline()
if not line:
sleep(1)
else:
print line
file.close()
All works fine but the C implementation is not working (there are no check-error code). The inclusion of stdio.h, string.h and unistd.h is omitted (the colorization hides the header inclusion code).
#define LINE_LEN 256
int main(int argc, char **argv)
{
FILE *f;
char line[LINE_LEN];
f = fopen("file.txt", "r");
fseek(f, 0, SEEK_END);
while (1)
{
fgets(line, LINE_LEN, f);
if (strlen(line) == 0)
{
sleep(1);
}
else
{
printf("Readed: %s", line);
}
}
fclose(f);
return 0;
}
Some idea?
Is a good idea implement it with a poll() instead the presented solution?.
Thanks in advance.
Upvotes: 2
Views: 1864
Reputation: 79790
EDIT: Seems like inotify is the thing to use. It should be included in linux kernel since 2.6.13 . An article from IBM developerworks about inotify.
Previous answer:
Have a look at Linux File Alteration Monitor (in linux kernels 2.4.x >). It's a framework that let's you subscribe for file changes and you get callback from kernel when change happens. This should be better than polling.
Examples how to poll for file changes, check out sections Waiting for file changes and Polling for file changes.
I haven't tried it yet.
Upvotes: 3
Reputation: 19353
From the tail
man page:
-f Do not stop when end-of-file is reached, but rather to wait for additional data to be appended to the input. If the file is replaced (i.e., the inode number changes), tail will reopen the file and continue. If the file is truncated, tail will reset its position to the beginning. This makes tail more useful for watching log files that may get rotated. The -f option is ignored if the standard input is a pipe, but not if it is a FIFO.
So, you could do the same thing:
Upvotes: 2
Reputation: 2960
Once a FILE * has seen an error or eof, it has its internal status set so that it continues to return error or eof on subsequent calls. You need to call clearerr(f);
after the sleep returns to clear the eof setting and get it to try to read more data from the file.
Upvotes: 3