inotify file in C

inotify-tools
inotify/max_user_instances
inotify permissions
fanotify vs inotify
linux monitor file changes c
c monitor file changes
inotify queue overflow
incron vs inotify

I am trying to run an example of inotify in C..but it's not working. I want to monitor modifications to a file (the file is tmp.cfg), but it doesn't work..I don't know if i'm running it correctly, because I understand how to monitor directories, but not a single file Here´s the example:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/inotify.h>
#include <unistd.h>

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

int main( int argc, char **argv )
{
  int length, i = 0;
  int fd;
  int wd;
  char buffer[BUF_LEN];

  fd = inotify_init();

  if ( fd < 0 ) {
    perror( "inotify_init" );
  }

  wd = inotify_add_watch( fd, "/home/name/tmp.cfg",
                         IN_MODIFY | IN_CREATE | IN_DELETE );
  length = read( fd, buffer, BUF_LEN );

  if ( length < 0 ) {
    perror( "read" );
  }

  while ( i < length ) {
    struct inotify_event *event = ( struct inotify_event * ) &buffer[ i ];
      if ( event->mask & IN_CREATE ) {
          printf( "The file %s was created.\n", event->name );
      }
      else if ( event->mask & IN_DELETE ) {
          printf( "The file %s was deleted.\n", event->name );
      }
      else if ( event->mask & IN_MODIFY ) {
          printf( "The file %s was modified.\n", event->name );
      }
    i += EVENT_SIZE + event->len;
  }

  ( void ) inotify_rm_watch( fd, wd );
  ( void ) close( fd );

  return 0;
}

Once i run it, if i write something on the file and then save it, nothing happens. i've tryed debugging it..the problem seems to be the if ( event->mask & IN_MODIFY ), as it doesn't recognize it as a modification

You have 2 issues. First, as far as I can tell, inotify does not really work on files - it needs directory name to watch.

Second, you missed if (event->len) { inside while loop.

This code works for me for creating, deleting and modifying files in current directory:

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/inotify.h>
#include <unistd.h>

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

int main(int argc, char **argv) {
    int length, i = 0;
    int fd;
    int wd;
    char buffer[BUF_LEN];

    fd = inotify_init();

    if (fd < 0) {
        perror("inotify_init");
    }

    wd = inotify_add_watch(fd, ".",
        IN_MODIFY | IN_CREATE | IN_DELETE);
    length = read(fd, buffer, BUF_LEN);

    if (length < 0) {
        perror("read");
    }

    while (i < length) {
        struct inotify_event *event =
            (struct inotify_event *) &buffer[i];
        if (event->len) {
            if (event->mask & IN_CREATE) {
                printf("The file %s was created.\n", event->name);
            } else if (event->mask & IN_DELETE) {
                printf("The file %s was deleted.\n", event->name);
            } else if (event->mask & IN_MODIFY) {
                printf("The file %s was modified.\n", event->name);
            }
        }
        i += EVENT_SIZE + event->len;
    }

    (void) inotify_rm_watch(fd, wd);
    (void) close(fd);

    return 0;
}

inotify file in C, +/* demo_inotify.c + + Demonstrate the use of the inotify API. program monitors each of the files specified on the command line for all + possible file events. 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().

I think you're not using your user name, which is your home directory, and you're not checking the return of inotify_add_watch which probably fails:

"/home/name/tmp.cfg"

Edit: okay second problem, you shouldn't print name because

The name field is only present when an event is returned for a file inside a watched directory;

Edit2: third problem, the file must exist before you run the program because you add a watch on the file, I suggest you check the error from inotify_add_watch

inotify/demo_inotify.c (from "The Linux Programming Interface"), * When events occur for monitored files and directories, those events are made available to the application as structured data that can be read from the inotify file​  The inotify API provides a mechanism for monitoring file system events. Inotify can be used to monitor individual files, or to monitor directories. When a directory is monitored, inotify will return events for the directory itself, and for files inside the directory.

In watching a file, if the file is manipulated by an editor which you might do to edit it and create a change, it is likely to be doing some operations that results in the original file you asked to watch being deleted. Hence the notifications will stop if you only watch the one file.

inotify(7) - Linux manual page, This is a short introduction to using the inofity api in linux to detect file [ch]'" which will run make any time any of the .c, .h files change. the  Linux has an efficient method for alerting user-space processes to changes impacting files of interest. The inotify Linux system calls were first discussed here in Linux Journal in a 2005 article by Robert Love who primarily addressed the behavior of the new features from the perspective of C.

It doesn't work on a single file because, when we use a editor to modify file, the editor opens a copy of the file and when we save the edited version from the text editor, the existing file is deleted and a new file of the same name is created with the modifications.

When the old file is deleted, the watch created on that file becomes invalid and it is deleted automatically.

You can see the old file being replaced by the new file if you monitor the parent directory.

There are two ways to solve it, monitor the parent directory and print the message when modifications is done to the particular that you want to watch.

Else create a new watch on the file whenever modifications are made. When the old file is deleted, IN_DELETE_SELF event is triggered.

event->name will be non-empty only when you watch a directory, as it will contain the name of the file on which the event has occurred in the watched directory.

Linux Programming, h in your C program. Watches. A watch is at the core of Inotify. You use a watch to specify the directory or file you are interested in monitoring for  C program to monitor and notify changes in a directory / file using inotify C Programs , Linux, OS Concepts and Networking , OS Concepts , Programming Languages / $ vim notify.c

Getting Started with Inotify, C program to monitor and notify changes in a directory / file using inotify. C Programs #define EVENT_SIZE ( sizeof (struct inotify_event) ) /*size of one event*/. inotify/demo_inotify.c. This is inotify/demo_inotify.c (Listing 19-1, page 382), an example from the book, The Linux Programming Interface. The source code file is copyright 2010, Michael Kerrisk, and is licensed under the GNU General Public License, version 3.

C program to monitor and notify changes in a directory / file using , kernel subsystem that acts to extend filesystems to notice changes to the filesystem, and report those changes to applications. It replaces an earlier facility, dnotify, which had similar goals. The set of watch descriptors that is being monitored via an inotify file descriptor can be viewed via the entry for the inotify file descriptor in the process's /proc/[pid]/fdinfo directory. See proc(5) for further details. The FIONREAD ioctl(2) returns the number of bytes available to read from an inotify file descriptor.

inotify, wh5a/inotify.c. Created 10 A simple inotify example from https://www.ibm.com/​developerworks/linux/library/l-ubuntu-inotify/ */ printf( "The file %s was created. The inotify C API. inotify provides three system calls to build file system monitors of all kinds: inotify_init() creates an instance of the inotify subsystem in the kernel and returns a file descriptor on success and -1 on failure. Like other system calls, if inotify_init() fails, check errno for diagnostics.

Comments
  • You may be right. However, if I use file name, change notification does not seem to work for me
  • the name shouldn't be printed too because that's only there when a file in watched directory changes.
  • Ah, I see. But it only works if file already existed. Seems like watching directory and comparing for file name is more robust (but could be slow if other files change)
  • yes the file must be there first, because the watch is added on the file.
  • For some reason it doesn't work with files..i don't know why, because when i try inotify for directories it works fine.
  • i've tryed debugging it..the problem seems to be the if ( event->mask & IN_MODIFY ), as it doesn't recognize it as a modification
  • @user1693049 I tried the code and it works here, don't see any problem with it