≡ Menu

Inotify Example: Introduction to Inotify with a C Program Example

inotify utility is an effective tool to monitor and notify filesystem changes.  You can specify a list of files and directories that needs to be monitored by inotify. This library is used by various other programs. For example, CPAN module Linux::Inotify is developed based on this library.

iNotify Execution Flow

On a high-level, you do the following with inotify utility.

  • Create inotify monitoring list. Add the desired directories/files to the inotify monitoring list. Monitoring list can be changed as and when needed
  • Request Inotify to report specific event changes to the monitoring list of files and directories. For example, request inotify to report ON ACCESS, ON OPEN, ON WRITING, ON CLOSE,etc.,

Following are the inotify functions and their corresponding roles.

  • Create the inotify instance by inotify_init().
  • Add all the directories to be monitored to the inotify list using inotify_add_watch() function.
  • To determine the events occurred, do the read() on the inotify instance. This read will get blocked till the change event occurs. It is recommended to perform selective read on this inotify instance using select() call.
  • Read returns list of events occurred on the monitored directories. Based on the return value of read(), we will know exactly what kind of changes occurred.
  • In case of removing the watch on directories / files, call inotify_rm_watch().

Be careful when using this module with NFS filesystem. It might not determine the events changes to the monitoring list that contains files/directories from the NFS filesystem.

Inotify Events

Following are the available inotify events:

  • IN_ACCESS – File was accessed
  • IN_ATTRIB – Metadata changed (permissions, timestamps, extended attributes, etc.)
  • IN_CLOSE_WRITE – File opened for writing was closed
  • IN_CLOSE_NOWRITE – File not opened for writing was closed
  • IN_CREATE – File/directory created in watched directory
  • IN_DELETE – File/directory deleted from watched directory
  • IN_DELETE_SELF – Watched file/directory was itself deleted
  • IN_MODIFY – File was modified
  • IN_MOVE_SELF – Watched file/directory was itself moved
  • IN_MOVED_FROM – File moved out of watched directory
  • IN_MOVED_TO – File moved into watched directory
  • IN_OPEN – File was opened

Recommended modules / libraries for iNotify

Make sure libc6 2.3.6 module is installed on your system. If you have a previous version of libc module installed, you will get the following error message while compiling the inotify monitoring c program.

error: linux/inotify.h: No such file or directory

Check the libc6 version on your system and upgrade it if required.

# dpkg -l libc6

Sample C program for Monitoring of File/directory changes event

/*This is the sample program to notify us for the file creation and file deletion takes place in “/tmp” directory*/
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <linux/inotify.h>

#define EVENT_SIZE  ( sizeof (struct inotify_event) )
#define EVENT_BUF_LEN     ( 1024 * ( EVENT_SIZE + 16 ) )

int main( )
{
  int length, i = 0;
  int fd;
  int wd;
  char buffer[EVENT_BUF_LEN];

  /*creating the INOTIFY instance*/
  fd = inotify_init();

  /*checking for error*/
  if ( fd < 0 ) {
    perror( "inotify_init" );
  }

  /*adding the “/tmp” directory into watch list. Here, the suggestion is to validate the existence of the directory before adding into monitoring list.*/
  wd = inotify_add_watch( fd, "/tmp", IN_CREATE | IN_DELETE );

  /*read to determine the event change happens on “/tmp” directory. Actually this read blocks until the change event occurs*/ 

  length = read( fd, buffer, EVENT_BUF_LEN ); 

  /*checking for error*/
  if ( length < 0 ) {
    perror( "read" );
  }  

  /*actually read return the list of change events happens. Here, read the change event one by one and process it accordingly.*/
  while ( i < length ) {     struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ];     if ( event->len ) {
      if ( event->mask & IN_CREATE ) {
        if ( event->mask & IN_ISDIR ) {
          printf( "New directory %s created.\n", event->name );
        }
        else {
          printf( "New file %s created.\n", event->name );
        }
      }
      else if ( event->mask & IN_DELETE ) {
        if ( event->mask & IN_ISDIR ) {
          printf( "Directory %s deleted.\n", event->name );
        }
        else {
          printf( "File %s deleted.\n", event->name );
        }
      }
    }
    i += EVENT_SIZE + event->len;
  }
  /*removing the “/tmp” directory from the watch list.*/
   inotify_rm_watch( fd, wd );

  /*closing the INOTIFY instance*/
   close( fd );

}
Add your comment

If you enjoyed this article, you might also like..

  1. 50 Linux Sysadmin Tutorials
  2. 50 Most Frequently Used Linux Commands (With Examples)
  3. Top 25 Best Linux Performance Monitoring and Debugging Tools
  4. Mommy, I found it! – 15 Practical Linux Find Command Examples
  5. Linux 101 Hacks 2nd Edition eBook Linux 101 Hacks Book

Bash 101 Hacks Book Sed and Awk 101 Hacks Book Nagios Core 3 Book Vim 101 Hacks Book

Comments on this entry are closed.

  • madskaddie April 16, 2010, 3:38 am

    Excelent tutorial!

  • siniranji April 16, 2010, 3:50 am

    you really impress me, you know the need of the hour, please post me how i can find out unused email accounts in my mail server (rhel 4 update 2) squriel mail.

  • ChineseGeek April 16, 2010, 7:27 am

    There’s a mistake in line 31. Thank u!

  • adiascem April 16, 2010, 8:27 am

    length = read( fd, buffer, BUF_LEN ); /*change BUF_LEN to EVENT_BUF_LEN*/

  • Ramesh Natarajan April 16, 2010, 9:56 am

    @ChineseGeek, @adiascem,

    Thanks for pointing out the issue. I’ve fixed it.

  • ChineseGeek April 16, 2010, 10:33 am

    No problem! Great blog by the way!

  • scott April 16, 2010, 2:07 pm

    Ramesh: Can you give us an example of where (why) you’d use inotify.
    Thx!
    -Scott

  • Suhas MK April 17, 2010, 2:19 pm

    Informative and helpful. Thank You.

  • RogueWarrior65 April 18, 2010, 9:26 pm

    This doesn’t work for me. When I run it, it tells me /lib/libc.so.6: version `GLIBC_2.4′ not found. I checked dpkg -l libc6 and it says “ii libc6 2.3.6.ds1-13et GNU C Library: Shared libraries”

  • Anonymous March 25, 2011, 2:23 am

    do u hav any program regarding Graphic…

  • John Hascall May 18, 2011, 3:02 pm

    You should use
    #include
    rather than
    #include

    Also, the program would be more interesting if you added an outer loop:
    for (;;) {
    length = read( fd …

    }
    inotify_rm_watch( …

    so you’d get more than one event per run.

  • John Hascall May 18, 2011, 3:03 pm

    Arrrg, your comment thingy ate the angle brackets!
    anyway, include sys/inotify.h instead of linux/inotify.h

  • Lakshmanan September 17, 2011, 1:49 am

    Does, inofify works on /proc file system. I’ve just tested it, and it seems it is not working.

  • Jörg Sonnenberger June 10, 2013, 3:04 am

    It should be noted that the buf usage can create problems on strict alignment platforms. You might want to use a separate inotify_event structure and memcpy from the read buffer to avoid that.

  • Sascha October 28, 2013, 5:09 am

    Hi,
    What are these 16 and 1024 e.g.:
    #define EVENT_BUF_LEN ( 1024 * ( EVENT_SIZE + 16 ) )

    Appreciate a fast response from anybody who has figured this out:)

  • Danny June 9, 2014, 3:44 pm

    Sascha – I know this isn’t a “fast” response, but… The 1024 is “make a buffer that can hold 1024 events”. The 16 is, as far as I can tell, a typo. The size of an inotify event is the size of the struct, plus the length of the filename (that would be the full path), plus a null character. So, this example is seemingly assuming that filenames average 15 characters. To err on the other side of caution, you could assume that every event has the maximum filename length, defined by the “NAME_MAX” constant. That’s defined in limits.h, and is 255 on my Linux systems. In any event, the buffer length there is expressing the number of events to be stored times the rough size of each event. Using “EVENT_SIZE + NAME_MAX +1” would give you the largest possible event size, but you could save some memory by properly analyzing your data beforehand, either programmatically before dynamically allocating the buffer or by some other more static means.

  • Anonymous August 8, 2014, 11:20 am

    how can we monitor rename of file

  • Pramod February 27, 2015, 5:09 am

    HI,

    I want to monitor a particular file; not a directory. How can I use i notify for this ? Please help.

  • karthik July 17, 2015, 12:43 am

    Thanks a lot Ramesh…i just read and used your code for my application

  • Prabha February 7, 2017, 4:15 am

    Hi Ramesh, When I run the code, I am getting empty buffer on any event.
    how to debug this.