A simple application using io.monitor: a tail -f replacement
Tuesday, February 5, 2008
The tail
command on Unix shows the end of a file. If you pass it the
-f
switch it monitors the file for changes and emits any lines written
to the end. This is frequently used to watch log files. Traditionally it
was implemented by polling but on modern systems it uses file system
change notification APIs.
Here is an example that Factor’s file system change notification
API.
Note that I renamed the io.monitor
vocabulary to io.monitors
. This
demo works on Linux and Windows.
We begin with the customary boilerplate:
USING: kernel io io.files io.monitors ;
IN: log-viewer
First, we need a word which reads lines from a stream until EOF and prints them. Note that the stream isn’t closed here.
: read-lines ( stream -- )
dup stream-readln dup [ print read-lines ] [ 2drop ] if ;
Next, a recursive word which takes a stream and a monitor; it reads any lines until EOF, waits for the file to change, then calls itself again:
: tail-file-loop ( stream monitor -- )
over read-lines
dup next-change 2drop
tail-file-loop ;
Finally, a word which puts everything together. It takes a file name, opens it for reading, and creates a monitor on its parent directory:
: tail-file ( file -- )
dup <file-reader> swap parent-directory f <monitor>
tail-file-loop ;