Wednesday, December 05, 2007

Linux inotify example


#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <sys/inotify.h>

void get_event (int fd, const char * target);
void handle_error (int error);

/* ----------------------------------------------------------------- */

int main (int argc, char *argv[])
{
char target[FILENAME_MAX];
int result;
int fd;
int wd; /* watch descriptor */

if (argc < 2) {
fprintf (stderr, "Watching the current directory\n");
strcpy (target, ".");
}
else {
fprintf (stderr, "Watching %s\n", argv[1]);
strcpy (target, argv[1]);
}

fd = inotify_init();
if (fd < 0) {
handle_error (errno);
return 1;
}

wd = inotify_add_watch (fd, target, IN_ALL_EVENTS);
if (wd < 0) {
handle_error (errno);
return 1;
}

while (1) {
get_event(fd, target);
}

return 0;
}

/* ----------------------------------------------------------------- */
/* Allow for 1024 simultanious events */
#define BUFF_SIZE ((sizeof(struct inotify_event)+FILENAME_MAX)*1024)

void get_event (int fd, const char * target)
{
ssize_t len, i = 0;
char action[81+FILENAME_MAX] = {0};
char buff[BUFF_SIZE] = {0};

len = read (fd, buff, BUFF_SIZE);

while (i < len) {
struct inotify_event *pevent = (struct inotify_event *)&buff[i];
char action[81+FILENAME_MAX] = {0};

if (pevent->len)
strcpy (action, pevent->name);
else
strcpy (action, target);

if (pevent->mask & IN_ACCESS)
strcat(action, " was read");
if (pevent->mask & IN_ATTRIB)
strcat(action, " Metadata changed");
if (pevent->mask & IN_CLOSE_WRITE)
strcat(action, " opened for writing was closed");
if (pevent->mask & IN_CLOSE_NOWRITE)
strcat(action, " not opened for writing was closed");
if (pevent->mask & IN_CREATE)
strcat(action, " created in watched directory");
if (pevent->mask & IN_DELETE)
strcat(action, " deleted from watched directory");
if (pevent->mask & IN_DELETE_SELF)
strcat(action, "Watched file/directory was itself deleted");
if (pevent->mask & IN_MODIFY)
strcat(action, " was modified");
if (pevent->mask & IN_MOVE_SELF)
strcat(action, "Watched file/directory was itself moved");
if (pevent->mask & IN_MOVED_FROM)
strcat(action, " moved out of watched directory");
if (pevent->mask & IN_MOVED_TO)
strcat(action, " moved into watched directory");
if (pevent->mask & IN_OPEN)
strcat(action, " was opened");

/*
printf ("wd=%d mask=%d cookie=%d len=%d dir=%s\n",
pevent->wd, pevent->mask, pevent->cookie, pevent->len,
(pevent->mask & IN_ISDIR)?"yes":"no");

if (pevent->len) printf ("name=%s\n", pevent->name);
*/

printf ("%s\n", action);

i += sizeof(struct inotify_event) + pevent->len;

}

} /* get_event */

/* ----------------------------------------------------------------- */

void handle_error (int error)
{
fprintf (stderr, "Error: %s\n", strerror(error));

} /* handle_error */

/* ----------------------------------------------------------------- */

22 comments:

Peter Teoh said...

Thank you for the example......fantastic sharing....I was searching for it.

Beket said...

Great example! Thanks!

Valeriano said...

Cool, now I try to run it on lenny

Mayur said...

It's very nice code, Thanks

Ivo said...

Just perfect. It is exactly the example I need.

Valeriano said...

Hello guys,

someone have a similar example that work on windows, in C or C++ ?

Clive said...

Of course! But the API is different. I'll generate a new post, its too big for a comment.

naren said...

excellent

shadyabhi said...

Thanx.. I really wanted a code like this..

Debsankha said...

Thanks for this code. The variable size of struct inotify_event causing all sorts of problems in my code and I was totally at a loss until I saw your example.

Annie Calvert said...

I loved your blog article.Really thank you! Will read on…
dotnetgrid

Jaga said...

can you explain this code functionality.i want to write php script to notify files

govardhan reddy said...

hi pal. i seen your program . it working for particular path like /tmp/Untitled Folder.
but i need to monitor subdirectory dynamically with out giving the command line arg.
eg: i monitored the " /media " path when ever i insert the usb(pen-drive) it shows.but i need to monitor that usb (pen-drive ) simultaneously.like if i copy the file from system to pendrive or pen drive to system i need to monitor that thing ..please help me out .thanks in advance.

Sri said...

Hi, am getting the following error, at len = read (fd, buff, BUFF_SIZE);, that `read` was not declared in this scope? help me thanks...

Clive said...

Probably:

#include <unistd.h>

Check with:

man 2 read

Stephen Donovan said...

The SBOK guide of http://www.scrumstudy.com will give you a clear understanding of how to run effective daily standup meetings. It also provides you detailed information on Agile Project Management methodologies suchas planning/review/retrospective meeting, and how to take advantages of related tools and so on.

Kenley William said...

The PMP Certification establishes a common language among project managers and helps each other work within a common framework. Once you have the PMP, you need to consider how you're applying the processes, tools, and techniques to projects. I took a training course for my preparation in http://www.pmstudy.com and got ready for the exam on day 5!

Olivia Jennifer said...
This comment has been removed by the author.
Sarah Nelson said...
This comment has been removed by the author.
Sarah Nelson said...
This comment has been removed by the author.
Sarah Nelson said...

Scrum study also has interesting ways to teach the students for
agile scrum certification ( Scrum Master Certification ) courses. check their website for some free introductory course in scrum.

Olivia Jennifer said...

To stop making avoidable mistakes in project management one can also try attending good PMP classes conducted by any of the PMI registered REP's for gainig expertise best processes of project management. Any good PMP prep course will provide students with lots of actionable insights in project management along with preparing them for PMP certification.