inotify1.c 2.52 KB
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/select.h>

#include <inotify.h>

int
main (int arg, char * argv [])
{
	int    notify_d,
	       watch_id;
	fd_set rfds;
	int    sel_ret;

	FD_ZERO (&rfds);

	notify_d = inotify_init ();
	if (notify_d == -1)
	{
		perror ("could not init inotify");
		return 1;
	}

	FD_SET  (notify_d, &rfds);

	watch_id = inotify_add_watch (notify_d, argv[1], 
	                              IN_CREATE|IN_OPEN|IN_MODIFY|IN_CLOSE);
	if (watch_id == -1)
	{
		perror ("could not add watch");
		return 2;
	}

	while (sel_ret = select (notify_d+1, &rfds, NULL, NULL, NULL)) 
	{
		char *                 in_ev   = NULL;
		struct inotify_event * act_ev  = NULL;
		size_t                 size    = 0;
		size_t                 size_avail;
		char *                 ev_name = NULL;

		ioctl (notify_d, FIONREAD, &size_avail);
		in_ev = (char *)malloc (size_avail);
		if (in_ev == NULL)
		{
			perror ("could not get memory for event list");
			return 4;
		}
		memset (in_ev, 0, size_avail);

		while (size < size_avail)
		{
			int got = read (notify_d, in_ev + size, 
			                size_avail - size);
			if (got == 0)
			{
				perror ("notify FD was closed unexpectedly");
				return 3;
			}
			size += got;
		}

		for (act_ev = (struct inotify_event *) in_ev; 
		     (char *) act_ev < in_ev + size_avail && IN_NO_EVENT (act_ev);
			  act_ev = IN_NEXT_EVENT (act_ev))
		{
			printf ("Watch Descriptor: %d\n", act_ev->wd);
			switch (act_ev->mask)
			{
				case IN_ACCESS:
					ev_name = "IN_ACCESS"; break;
				case IN_ATTRIB:
					ev_name = "IN_ATTRIB"; break;
				case IN_CLOSE_WRITE:
					ev_name = "IN_CLOSE_WRITE"; break;
				case IN_CLOSE_NOWRITE:
					ev_name = "IN_CLOSE_NOWRITE"; break;
				case IN_CREATE:
					ev_name = "IN_CREATE"; break;
				case IN_DELETE:
					ev_name = "IN_DELETE"; break;
				case IN_DELETE_SELF:
					ev_name = "IN_DELETE_SELF"; break;
				case IN_MODIFY:
					ev_name = "IN_MODIFY"; break;
				case IN_MOVE_SELF:
					ev_name = "IN_MOVE_SELF"; break;
				case IN_MOVED_FROM:
					ev_name = "IN_MOVED_FROM"; break;
				case IN_MOVED_TO:
					ev_name = "IN_MOVED_TO"; break;
				case IN_OPEN:
					ev_name = "IN_OPEN"; break;
			}
			printf ("Mask of Events:   %s(%d)\n", ev_name, act_ev->mask);
			printf ("Events Cookie:    %u\n", act_ev->cookie);
			printf ("Length of name:   %u\n", act_ev->len);
			printf ("Event Name:       %s\n", act_ev->name);
		}

		if (in_ev)
		{
			free (in_ev);
			in_ev = NULL;
		}

		puts ("---");

		FD_SET  (notify_d, &rfds);
	}

	return 0;
}