A naive implementation of tail
is to read the file sequentially
from the beginning, keeping the last n lines read in a circular
buffer. When we reach the end of file, we display the buffer.
When the data comes from a pipe or a special file which
does not implement lseek
, there is no better way.
However if the data is coming from a normal file, it is better to read
the file from the end. With lseek
, we read the last 4096
characters. We scan them for the end of lines. If there are at least
n of them, we output and display the corresponding lines.
Otherwise, we start again by adding the next preceding 4096
characters, etc.
To add the option -f
, we first proceed as above and then we go
back at the end of the file and try to read
from there. If
read
returns data we display it immediately and start again. If it
returns 0
we wait some time (sleep 1
) and try again.