Chinaunix首页 | 论坛 | 博客
  • 博客访问: 5699963
  • 博文数量: 675
  • 博客积分: 20301
  • 博客等级: 上将
  • 技术积分: 7671
  • 用 户 组: 普通用户
  • 注册时间: 2005-12-31 16:15
文章分类

全部博文(675)

文章存档

2012年(1)

2011年(20)

2010年(14)

2009年(63)

2008年(118)

2007年(141)

2006年(318)

分类: LINUX

2008-08-24 21:13:56


inotify是2.6.13内核引入的,用来替换dnotify的,实现了一套文件系统监控机制。

Inotify 可以监视的文件系统事件包括:

  • IN_ACCESS,即文件被访问
  • IN_MODIFY,文件被 write
  • IN_ATTRIB,文件属性被修改,如 chmod、chown、touch 等
  • IN_CLOSE_WRITE,可写文件被 close
  • IN_CLOSE_NOWRITE,不可写文件被 close
  • IN_OPEN,文件被 open
  • IN_MOVED_FROM,文件被移走,如 mv
  • IN_MOVED_TO,文件被移来,如 mv、cp
  • IN_CREATE,创建新文件
  • IN_DELETE,文件被删除,如 rm
  • IN_DELETE_SELF,自删除,即一个可执行文件在执行时删除自己
  • IN_MOVE_SELF,自移动,即一个可执行文件在执行时移动自己
  • IN_UNMOUNT,宿主文件系统被 umount
  • IN_CLOSE,文件被关闭,等同于(IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)
  • IN_MOVE,文件被移动,等同于(IN_MOVED_FROM | IN_MOVED_TO)

inotifytools_sprintf
  • %w - This will be replaced with the name of the Watched file on which an event occurred.
  • %f - When an event occurs within a directory, this will be replaced with the name of the File which caused the event to occur. Otherwise, this will be replaced with an empty string.
  • %e - Replaced with the Event(s) which occurred, comma-separated.
  • %Xe - Replaced with the Event(s) which occurred, separated by whichever character is in the place of `X'.
  • %T - Replaced by the current Time in the format specified by the string previously passed to , or replaced with an empty string if that function has never been called.

%w,将会被当事件发生时检测文件的名字所替换
%f,将会被当一个事件在一个目录下发生时,导致事件发生的文件的名字所替换
%e,将会被发生的事件,以逗号作为间隔所替换
%Xe,将会被发生的事件,以"X"表示的符号作为间隔所替换
%T,将会被之前设置的时间格式所替换。

NOTES:这里需要注意%w和%f。
%w,是在检测域中检测的文件,也就是调用inotifytools_watch_recursively类函数的文件(包括路径)
%f,是引发相应事件的文件(前提是在一个目录下面进行检测,如果检测对象是一个文件,那么%f一般为空)

%w和%f可以不是一个,例如,test是一个目录,我们在test下面检测MOVED_TO事件,当move一个文件a.txt到test目录中时候 ,a.txt将会触发一个MOVED_TO事件。在这里,test是检测文件,a.txt是引发事件的文件。
如 果调用inotifytools_watch_file的话,使用%f实际上是无效的,因为%f仅用于事件作用于一个目录的情况,实际上也就是说 inotifytools_watch_recursively将会检测目录及其目录下面的递归子目录,但是不包括各个子目录下面的文件。
inotify_watch_file不能够从字面上进行理解,它不仅仅可以检测文件,还可以检测目录的,inotify检测的是inode,所以目录文件均可。

例如,我们要检测移动文件到相应目录下面的应用:
#include
#include
#include
#include

#define INOTIFY_PATH "./xml/"
/*
 * libinotifytools example program.
 * Compile with gcc -linotifytools example.c
 */
int main(int argc, char *argv[]) {

    char fname[1024];
        // initialize and watch the entire directory tree from the current working
        // directory downwards for all events
        if ( !inotifytools_initialize()
          || !inotifytools_watch_file( INOTIFY_PATH, IN_MOVED_TO ) ) {
                fprintf(stderr, "%s\n", strerror( inotifytools_error() ) );
                return -1;
        }

    //inotifytools_watch_file("./a", IN_CLOSE_WRITE);
        // set time format to 24 hour time, HH:MM:SS
        inotifytools_set_printf_timefmt( "%T" );

        // Output all events as " "
        struct inotify_event * event = inotifytools_next_event( -1 );
        while ( event ) {
                inotifytools_printf( event, "%T %w%f %e\n" );
        memset(fname, 0, sizeof(fname));
        inotifytools_sprintf(fname, event, "%w%f");

        //printf("watches: %d\n", inotifytools_get_num_watches() );
        printf("fname: %s\n", fname);

                event = inotifytools_next_event( -1 );
        }

    inotifytools_cleanup();
}

这里没有必要使用inotifytools_watch_recursively。

======
递归侦测的时候,不能保证原子性(inotify不支持递归,递归是库自己添加的支持)。
"不能保证原子性"这个说法可能有些勉强,原文是这样的:
   This function does not attempt to work atomically. If you use this
function to watch a directory tree and files or directories are being
created or removed within that directory tree, there are no guarantees
as to whether or not those files will be watched.

查了一下libinotifytools的源代码,在第一次调用inotifytools_watch_recursively的时候,会递归的遍历目录,依次将每一层次的目录或者是文件添加到检测范围进行检测。但是,当出现了一个创建事件或者是删除事件,不能够实时的将新建的文件添加到检测范围,将删除的文件从检测范围中去除。

======
参考:

http://www.ibm.com/developerworks/cn/linux/l-inotifynew/
http://www.ibm.com/developerworks/cn/linux/l-inotify.html



阅读(2842) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~