introducing libinotify

due to my recent work with inotify i’m becoming increasingly convinced that a common library that provides a nice userspace interface to inotify is required. up until this point, everyone who wants to use inotify has written their own interface to it based on the raw syscalls. this means a lot of duplicated code and (probably) a lot of duplicated bugs.

a library with lots of users would carry all of the normal advantages of a single piece of code with many users. bugs are found more rapidly and these bug fixes help everyone. right now, if (for example) one of the beagle guys finds a bug in their implementation, then it gets fixed and nobody else benefits.

i also believe that a userspace library that provides an easy-to-use interface to inotify would make inotify more attractive to potential users.

as such, tonight i decided to release ‘libinotify’ based on the work i’ve been doing over the past week or so. it’s in gnome cvs with the module name ‘libinotify’.

it’s callback-based (with the customary user_data pointer) and it features automatic glib mainloop integration and a cracktastically easy-to-use public interface of two functions — inotify_monitor_add and inotify_monitor_remove. (there are some other functions but most users won’t need them.)

it tries to remain as true as is reasonable to the inotify api, allowing the user (for example) to deal natively with inotify event masks when requesting watches and receiving event notifications. it also provides the ‘name’ field of the event as reported by inotify (or null) directly to the user without any path fiddling.

perhaps most importantly, it handles the multiplexing that is required to support the user being able to register multiple watches on a single inode. it even allows multiple watches to be registered on the same inode with different event masks and calls callbacks only when they should be.

a very simple program might look like this:

#include <linux/inotify.h>
#include <libinotify.h>
#include <gtk/gtk.h>

static void
my_callback( INotifyHandle *inh, const char *monitor_name,
             const char *name, guint32 event_type,
             gpointer user_data )
{
  g_print( "Got event %x on %s (file %s)\n",
           event_type, monitor_name, name );
}

int main( int argc, char **argv )
{
  INotifyHandle *inh;

  gtk_init( &argc, &argv );

  inh = inotify_monitor_add( "/home/desrt", IN_ALL_EVENTS,
                              my_callback, NULL );

  if( inh == NULL )
    g_warning( "monitor_add failed" );

  /* maybe you want to do this later... */
  /* inotify_monitor_remove( inh ); */

  gtk_main();

  return 0;
}

as of now, there are still a few things left to implement. i need to figure out what (if anything) i want to do about reporting joint events (ie: moved_from/moved_to). also, the support for having multiple watches with different event masks doesn’t actually exist yet. the code isn’t yet very resilient against failure. the api is also very likely to change. as such, libinotify isn’t quite ready to be used for anything more than experimenting with.

i’m mostly making this post in hopes of receiving useful feedback. if you’re a current user of inotify (or plan to become one) i appreciate any thoughts or suggestions you might have regarding the direction of the libinotify api.

3 thoughts on “introducing libinotify”

  1. I am very excited by this new library you’ve come up with. I’ve wanted to start using inotify but due to lack of a simple api I felt I didn’t have the time to work on any such projects. This is a huge and very powerful addition to my arsenal of programming tools. Thanks much for your work on this.

  2. Excellent, looking forward to working with this library. Thanks!

  3. Hi,
    I am trying to build libinotigy, it failes with this error:
    inotify-monitor.c:248: error: ‘IN_MOVE_SELF’ undeclared (first use in this function)

    what am I missing?

Comments are closed.