“tail -f” is a special command in a way that it polls the specified file for any change and prints the new stuff on the fly. It is very helpful in observing logs and any event based data.

Ever wondered how tail achieves this?

“tail” opens the given file and obtains the file-descriptor. It opens it with xfreopen() -> freopen() -> fopen() call. It does its first round of fstat() on the file as well.

Once it has got the fd, it loops infinitely and do the following:

It does fstat() of the file and observes the mtime value. If the mtime value is changes from the last time..it dumps the data. To print the latest data, it lseek() the file to the last reported file size.

Source: http://git.savannah.gnu.org/cgit/coreutils.git/tree/src/tail.c

A strace of tail on my Ubuntu 11.04 is as follows:

kanaujia@ubuntu:~/Desktop/FUSE/dedup$ strace tail -f ./file.py 
execve("/usr/bin/tail", ["tail", "-f", "./file.py"], [/* 38 vars */]) = 0
brk(0)                                  = 0x9567000
open("./file.py", O_RDONLY|O_LARGEFILE) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=103, ...}) = 0
_llseek(3, 0, [0], SEEK_CUR)            = 0
_llseek(3, 0, [103], SEEK_END)          = 0
_llseek(3, 0, [0], SEEK_SET)            = 0
read(3, "FILE = open('./myfs/dood',\"w\")\np"..., 103) = 103
_llseek(3, 0, [0], SEEK_SET)            = 0
read(3, "FILE = open('./myfs/dood',\"w\")\np"..., 103) = 103
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 4), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb775c000
fstat64(3, {st_mode=S_IFREG|0644, st_size=103, ...}) = 0
fstatfs64(3, 84, {f_type="EXT2_SUPER_MAGIC", f_bsize=4096, f_blocks=4902319,
         f_bfree=3748629, f_bavail=3499605, f_files=1245184, f_ffree=1041484,
         f_fsid={598995932, 149996801}, f_namelen=255, f_frsize=4096}) = 0
inotify_init()                          = 4
inotify_add_watch(4, "./file.py", IN_MODIFY|IN_ATTRIB|IN_DELETE_SELF|IN_MOVE_SELF) = 1
fstat64(3, {st_mode=S_IFREG|0644, st_size=103, ...}) = 0
read(4, ....

So, it is using fstat and inotify API that add a watch to an initialized inotify instance.

About the Author Vishal

A voyager on the journey to technology and art of software development. Pursuing arts, music, photography, and ways to live life on the edge

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: