Linux file system events with C, Python and Ruby

Some applications (like file managers, monitoring tools, etc) need to know about events in the file system, for example when a file was created, opened or deleted.

With Linux, you can use the inotify mechanism to react to those events (with kernel 2.6.13 or above). In this article, I show you examples for it’s usage with C, Python and Ruby. In an upcoming post, we use Java 7 to monitor file events.

The C version

This code is relatively straightforward. You start the mechanism mit inotify_init(), add watches with inotify_add_watch, read the events from the inotify file descriptor and call the print_event function to print some information on stdout. Of course, depending on your software, you will do something completely different for each event.
The meaning of the events should be clear from the names of the constants. IN_CLOSE is used for closing a file after reading it or writing to it. You can also use two different events for those types of closing (IN_CLOSE_WRITE, IN_CLOSE_NOWRITE, see Python example below).
The inotify mechanism supports many more events than used in this example. See the man page for inotify for details.

If you use C++, you may want to have a look at this:
inotify C++ interface

Ruby Version

This uses the rb-inotify Ruby library. In this example, Ruby 1.9 was used.
To keep the example short, the Ruby version only watches events for a given directory (when a file is created or deleted). That should be enough to show you how the library works.
If you watch only one event, you don’t need the if behind the puts. I added this because I watch for several events but wanted different output for each event.
In order to watch for file events like in the C version, do the same thing for a file and use different events.
More information about the Ruby rb-inotify library can be found here:
http://rdoc.info/projects/nex3/rb-inotify

Python

The Python example used Python 3 (version 3.2 in my machine) as you can see by the way print is used (as a function).
In the Python example I used different handlers for IN_CLOSE_WRITE (used after a file was closed after writing something to it) and IN_CLOSE_NOWRITE (used after a file was closed after just reading the content).
You could write only one callback method process_IN_CLOSE to handle both events, but I wanted different output messages. And sometimes it is better to write a little more code to make it cleaer.

The pynotify module is available for both Python 2 and Python 3 and is very easy to use. More information can be found here:
https://github.com/seb-m/pyinotify/wiki

Conclusion

As you can see, listening to different file system events on Linux is not difficult using C, C++, Python or Ruby. The inotify mechanism is also available for other languages (for example, see here for a Haskell Version).

I prefer to use the Ruby or Python version over the C version as the source code is considerably shorter and easier to understand (as it is often the case with shorter code).
Of course it depends on your project. If you use C for your project, you have to go with the C version. If you just need a short script, for example for monitoring, I recommend going with the Ruby or Python solution (or a Perl implementation)

These examples only show some basic functionality of the inotify mechanism. For example, the Python version has different notifiers, for example a ThreadedNotifier. For more details, check the man pages and the documentation listed above. I hope this example serves as a starting point for your own programs.

Those modules and libraries are specific to Linux and won’t work on other operating systems. If you are a Java developer, you can use inotify-java, but this won’t be platform independent (which is often a goal for Java software).
In an upcoming posting, I will show you how to use the latest features of Java 7 to monitor file system events.