commit cd2869d251a7481eec4a0caf7e284a3c9fc26cb0 Author: Georg Hopp Date: Thu Mar 17 17:36:27 2016 +0100 initial checkin diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..71c3286 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,10 @@ + +INCLUDES = -I. -I./include @INOTIFY_INCLUDES@ + +bin_PROGRAMS = inotify + +inotify_SOURCES = inotify1.c +inotify_INCLUDES = inotify.h + +SUBDIRS = + diff --git a/bootstrap b/bootstrap new file mode 100755 index 0000000..c69f69e --- /dev/null +++ b/bootstrap @@ -0,0 +1,7 @@ +#!/bin/sh + +aclocal +libtoolize --copy +autoheader +automake --gnu --add-missing --copy +autoconf diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..7510c37 --- /dev/null +++ b/configure.ac @@ -0,0 +1,114 @@ +AC_PREREQ(2.68) +AC_INIT([checkout_files], + [0.0.1], + [georg@steffers.org]) +LT_INIT +AM_INIT_AUTOMAKE +AM_SILENT_RULES([no]) +AC_COPYRIGHT([Copyright © 2000 Georg Hopp]) +AC_REVISION([0.0.1]) +AC_CONFIG_SRCDIR([inotify1.c]) +AC_CONFIG_HEADER([config.h]) +AC_CONFIG_MACRO_DIR([m4]) + +AC_CANONICAL_HOST + +use_inotify="yes" + +# Checks for programs. +AC_PROG_CC +AC_PROG_MAKE_SET + +# Checks for header files. +AC_HEADER_STDC + +# Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST + +# Checks for library functions. +AC_CHECK_FUNCS([memset malloc free read ioctl syscall select perror printf]) + +dnl We need to check if the right inotify version is accessible +AC_MSG_CHECKING([whether inotify is to be used for filemonitoring]) +AC_ARG_ENABLE(inotify, + [ --disable-inotify disable inotify in the ecore_file module], + [ + if test "$enableval" == "yes"; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no - but we need it]) + use_inotify="no" + fi + ], [ + AC_MSG_RESULT([yes]) + ] +) + +dnl It's hard to find a good test on how to check the correct +dnl inotify version. They changed the headers a lot. +dnl in kernel 2.6.13 __NR_inotify_init was added to the defined syscalls +dnl in asm/unistd.h and IN_MOVE_SELF was added to linux/inotify.h +dnl so with this check you need a very new kernel and kernel-headers! +dnl On my gentoo, /usr/include/asm and /usr/include/linux are no symlinks +dnl into the current kernel tree....so i also try to find the includes +dnl under /usr/src/linux or under /usr/include/linux-`uname -r` +linux_rev=`uname -r` +INOTIFY_INCLUDES= +if test "x$use_inotify" = "xyes"; then + AC_MSG_CHECKING([for sufficient inotify includes]) + AC_TRY_COMPILE( + [ + #include + #include + ], + [ int a = __NR_inotify_init; int b = IN_MOVE_SELF; ], + [ + AC_DEFINE(HAVE_INOTIFY, 1, [ File monitoring with Inotify ]) + an_inc=/usr/include + ], + [ + AC_TRY_COMPILE( + [ + #include "/usr/src/linux/include/asm/unistd.h" + #include "/usr/src/linux/include/linux/inotify.h" + ], + [ int a = __NR_inotify_init; int b = IN_MOVE_SELF; ], + [ + AC_DEFINE(HAVE_INOTIFY, 1, [ File monitoring with Inotify ]) + AC_DEFINE(IN_KERNEL, 1, [ blablabla ]) + INOTIFY_INCLUDES=-I/usr/src/linux/include + an_inc=/usr/src/linux/include + ], + [ + AC_TRY_COMPILE( + [ + #include + #include + ], + [ int a = __NR_inotify_init; int b = IN_MOVE_SELF; ], + [ + AC_DEFINE(HAVE_INOTIFY, 1, [ File monitoring with Inotify ]) + AC_DEFINE(IN_KERNEL_UNAME, 1, [ blablabla ]) + INOTIFY_INCLUDES=-I/usr/src/linux-$linux_rev/include + an_inc=/usr/src/linux-$linux_rev/include + ], + [ + use_inotify="no" + an_inc="not found" + ] + ) + ] + ) + ] + ) + AC_MSG_RESULT([$an_inc]) + test "x$an_inc" == "xnot found" && exit +else + exit +fi + +AC_SUBST(INOTIFY_INCLUDES) + +AC_CONFIG_FILES([Makefile]) + +AC_OUTPUT diff --git a/inotify.h b/inotify.h new file mode 100644 index 0000000..aa4c08f --- /dev/null +++ b/inotify.h @@ -0,0 +1,30 @@ +#ifndef INOTIFY_H +#define INOTIFY_H + +#include +#include +#include + +#define IN_NEXT_EVENT(ev) \ + (struct inotify_event *) \ + ((char *)(ev) + sizeof (struct inotify_event) + (ev)->len) + +#define IN_NO_EVENT(ev) ((ev)->mask|IN_ALL_EVENTS) == IN_ALL_EVENTS + + +static inline int inotify_init (void) +{ + return syscall (__NR_inotify_init); +} + +static inline int inotify_add_watch (int fd, const char *name, __u32 mask) +{ + return syscall (__NR_inotify_add_watch, fd, name, mask); +} + +static inline int inotify_rm_watch (int fd, __u32 wd) +{ + return syscall (__NR_inotify_rm_watch, fd, wd); +} + +#endif /* INOTIFY_H */ diff --git a/inotify1.c b/inotify1.c new file mode 100644 index 0000000..e86c0c8 --- /dev/null +++ b/inotify1.c @@ -0,0 +1,115 @@ +#include +#include +#include +#include +#include + +#include + +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; +}