inotify例程

#include   
#include   
#include   
 
char * monitored_files[] = {   
    
"./tmp_file",   
    
"./tmp_dir",   
    
"/mnt/sda3/windows_file"   
};   
 
struct wd_name {   
    
int wd;   
    
char * name;   
};   
 
#define WD_NUM 3   
struct wd_name wd_array[WD_NUM]//用於存儲文件路徑名和watch描述符   
 
//inotify機制事件對應說明數組   
char * event_array[] = {   
    
"File was accessed",   
    
"File was modified",   
    
"File attributes were changed",   
    
"writtable file closed",   
    
"Unwrittable file closed",   
    
"File was opened",   
    
"File was moved from X",   
    
"File was moved to Y",   
    
"Subfile was created",   
    
"Subfile was deleted",   
    
"Self was deleted",   
    
"Self was moved",   
    
"",   
    
"Backing fs was unmounted",   
    
"Event queued overflowed",   
    
"File was ignored"   
};   
#define EVENT_NUM 16   
#define MAX_BUF_SIZE 1024   
 
int main(void)   
{   
    
int fd;   
    
int wd;   
    
char buffer[1024];   
    
char * offset = NULL;   
    
struct inotify_event * event;   
    
int len, tmp_len;   
    
char strbuf[16];   
    
int i = 0;   
 
    
fd = inotify_init();   
    
if (fd < 0) {   
        
printf("Fail to initialize inotify./n");   
        
exit(-1);   
 
    
}   
    
for (i=0; i< WD_NUM; i++) {   
        
wd_array<I>.name = monitored_files<I>;  //存入文件路徑名   
        
//給路徑wd_array<I>.name添加一個watch,監視所有事件,wd爲返回的watch描述符   
        
wd = inotify_add_watch(fd, wd_array<I>.name, IN_ALL_EVENTS);   
        
if (wd < 0) {   
            
printf("Can't add watch for %s./n", wd_array<I>.name);   
            
exit(-1);   
        
}   
 
        
wd_array<I>.wd = wd;   
    
}   
 
    
while(len = read(fd, buffer, MAX_BUF_SIZE)) { //讀取多個事件   
        
offset = buffer;   
        
printf("Some event happens, len = %d./n", len)//打印實際讀取的長度   
        
event = (struct inotify_event *)buffer; //得到事件   
 
        
while (((char *)event - buffer) < len) {   
            
if (event-> mask & IN_ISDIR) { //目錄   
                
memcpy(strbuf, "Direcotory", 11);     
                
//“Direcotory”字符串長度爲11   
            
}   
            
else {   
                
memcpy(strbuf, "File", 5);   
                
//“File”字符串長度爲5,包括後面加一個空格   
            
}   
            
printf("Object type: %s/n", strbuf);   
 
            
for (i=0; i< WD_NUM; i++) {   
                
if (event-> wd != wd_array<I>.wd)   
                    
continue;   
                
printf("Object name: %s/n", wd_array<I>.name);   
                
//打印文件路徑名   
                
break;   
            
}   
 
            
printf("Event mask: %08X/n", event-> mask)//打印事件掩碼   
            
for (i=0; i< EVENT_NUM ; i++) {   
                
if (event_array<I>[0] == '/0')   
                    
//空字符串行,說明事件對應說明不存在   
                    
continue;   
                
//將事件掩碼的位匹配數組成員,如:00000020,即100000,對應i爲5   
                
if (event-> mask & (1 << i)) {   
                    
printf("Event: %s/n", event_array<I>);     
                    
//打印事件對應的說明字符串   
                
}   
            
}   
 
            
tmp_len = sizeof(struct inotify_event) + event-> len;   
            
event = (struct inotify_event *)(offset + tmp_len)//得到下一個事件   
            
offset += tmp_len;   
        
}   
    
}   
}


C Code Snip

Incomplete, for a better example look at the Beagle source code in glue/inotify-glue.c.

// Initialize Inotify
fd = inotify_init ();
if (fd < 0) return -errno;

// Add a Watch
int wd;
wd = inotify_add_watch (fd, filename, mask);
if (wd < 0) return -errno;

// Read an inotify event (buffer should be at least the size of
static struc inotify_event *buffer = NULL;
buffer_size = sizeof (struct inotify_event);
*nr = read (fd, buffer, buffer_size);

inotify_rm_watch(wd);

PERL Code Snip

Using Linux::Inotify2, this package also allows the use of (really cool) callback functions on the watch. It's then up to the developer to call poll(), see the Linux::Inotify2 page for more information. This sample takes a more procedural approach.

use Linux::Inotify2;
my $inotify = new Linux::Inotify2();

foreach (@ARGV)
{
$inotify->watch($_, IN_ALL_EVENTS);
}

while (1)
{
# By default this will block until something is read
my @events = $inotify->read();
if (scalar(@events)==0)
{
print "read error: $!";
last;
}

foreach (@events)
{
printf "File: %s; Mask: %d/n", $_->fullname, $_->mask;
}


How it works

Inotify is used through a series of system calls specifically created for inotify.

int inotify_init()

Creates an inotify instance. Returns a file descriptor which all events are read from.

int inotify_add_watch(int fd, const char* pathname, int mask)

Starts watching the inode pointed to by pathname for events contained in mask. Returns a watch descriptor which is unique (within this inotify instance) to the inode pointed to by the pathname (NOTE: Multiple pathnames can point to the same inode/watch descriptor).

int inotify_rm_watch(int fd, int wd)

Cancels a watch on the given watch descriptor.

Events generated by inotify contain the following information:

Identifier Contents
wd watch descriptor
mask event tag
cookie cookie used to synchronize between IN_MOVED_FROM and IN_MOVED_TO
len length of name field
name the (optional) filename associated with this event (local to parent directory)

Some of the events that can be monitored for are:

  • IN_ACCESS - read of the file
  • IN_MODIFY - last modification
  • IN_ATTRIB - attributes of file change
  • IN_OPEN and IN_CLOSE - open or close of file
  • IN_MOVED_FROM and IN_MOVED_TO - when the file is moved or renamed
  • IN_DELETE - a file/directory deleted
  • IN_CREATE - a file/directory created
  • IN_DELETE_SELF - file monitored is deleted

}

參考:http://fanqiang.chinaunix.net/program/other/2005-05-10/3225.shtml
http://www.qqread.com/linux/2008/10/u435108_3.html
http://www.linuxjournal.com/article/8478
http://blog.csdn.net/absurd/archive/2007/06/18/1656944.aspx
http://blog.chinaunix.net/u/3425/showart_325415.html

QT 中也有相關的類,但要基於系統
發佈了37 篇原創文章 · 獲贊 3 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章