转一篇文章,linux文件访问notify机制 (2011-03-11 18:08)

分类:linux-program

一、dnotify机制1、使用通过对文件描述符设置监听信号实现。//设置文件相应信号fcntl(fd, F_SETSIG, SIGRTMIN + 1);//设置该文件要监听事件fcntl(fd, F_NOTIFY, DN_ACCESS|DN_MODIFY|DN_CREATE|DN_RENAME|DN_DELETE|DN_ATTRIB|DN_MULTISHOT);剩 下的就是信号处理了。2、缺点缺点1:dnotify机制对监视的每个文件夹都打开了一个文件描述符,如果文件夹所在文件系统需要 umount就不行了。缺点2:dnotify机制只能对文件夹进程监视。3、应用例子:

view plaincopy to clipboardprint?

    // 要用fcntl(fd,F_SETSIG,SIGRTMIN+1)就要设置这个宏#define_GNU_SOURCE1#include<fcntl.h>#include<stdio.h>#include<unistd.h>#include<signal.h>#defineFOLDER_MAXLEN128staticcharlisten_folder[FOLDER_MAXLEN];staticvoidmyhandler(int);intset_folder_signal(void){structsigactionact;intfd;act.sa_handler=myhandler;sigemptyset(&act.sa_mask);act.sa_flags=0;sigaction(SIGRTMIN+1,&act,NULL);if((fd=open(listen_folder,O_RDONLY))<0)return-1;printf("fd=%d\n",fd);fcntl(fd,F_SETSIG,SIGRTMIN+1);fcntl(fd,F_NOTIFY,DN_CREATE);return0;}intmain(intargc,char*argv[]){if(argc!=2){printf("%sfilepath\n",argv[0]);exit(0);}strncpy(listen_folder,argv[1],FOLDER_MAXLEN-1);if(set_folder_signal()<0){printf("setsignalto%sfail\n",argv[1]);exit(0);}while(1){pause();printf("asignalreturn\n");}}staticvoidmyhandler(intsigno){printf("signalno=%d,afilewascreat\n",signo);set_folder_signal();}

以上例子信号处理函数只能得到信号编号信息。可以通过sa_sigaction信号处理函数来获得更多信息,但也很有限。比如文件描述符。例 子:

view plaincopy to clipboardprint?

    //要用 fcntl(fd,F_SETSIG,SIGRTMIN+1)就要设置这个宏#define_GNU_SOURCE1#include<fcntl.h>#include<stdio.h>#include<unistd.h>#include<signal.h>#defineFOLDER_MAXLEN128staticcharlisten_folder[FOLDER_MAXLEN];staticvoidmyhandler(intsig,siginfo_t*si,void*data);intset_folder_signal(void){structsigactionact;intfd;act.sa_sigaction=myhandler;sigemptyset(&act.sa_mask);act.sa_flags=SA_SIGINFO;sigaction(SIGRTMIN+1,&act,NULL);if((fd=open(listen_folder,O_RDONLY))<0)return-1;printf("fd=%d\n",fd);fcntl(fd,F_SETSIG,SIGRTMIN+1);fcntl(fd,F_NOTIFY,DN_CREATE);return0;}intmain(intargc,char*argv[]){if(argc!=2){printf("%sfilepath\n",argv[0]);exit(0);}strncpy(listen_folder,argv[1],FOLDER_MAXLEN-1);if(set_folder_signal()<0){printf("setsignalto%sfail\n",argv[1]);exit(0);}while(1){pause();printf("asignalreturn\n");}}staticvoidmyhandler(intsigno,siginfo_t*si,void*data){printf("signalno=%d=%d,afilewascreat\n",signo,si->si_signo);printf("errno值=%d\n",si->si_errno);printf("信号产生的原因=%d\n",si->si_code);printf("产生信号的文件描述符=%d\n",si->si_fd);set_folder_signal();}

二、inotify机制(内核2.6.13以上版本才支持,你可以uname -a看看)1、使用#include <linux/inotify.h>//初始化inotify机制int inotify_init (void);//添加目录或文件进程监视int inotify_add_watch (int fd, const char *path, __u32 mask);//删除一个监视int inotify_rm_watch (int fd, __u32 mask);//获得监视事件反馈信息struct inotify_eventsize_t len = read (fd, buf, BUF_LEN);

struct inotify_event {__s32 wd; /* 监视描述符 */__u32 mask; /* 监视掩码 */__u32 len; /* 产生事件对象名称长度 */char name[0]; /* 产生事件对象名称 */};

inotify机制可以监视文件系统事件:IN_ACCESS,文件被访问IN_MODIFY,文件被 writeIN_ATTRIB, 文件属性被修改,如 chmod、chown、touch 等IN_CLOSE_WRITE,可写文件被 closeIN_CLOSE_NOWRITE, 不可写文件被 closeIN_OPEN,文件被 openIN_MOVED_FROM,文件被移走,如 mvIN_MOVED_TO, 文件被移来,如 mv、cpIN_CREATE,创建新文件IN_DELETE,文件被删除,如 rmIN_DELETE_SELF, 自删除,即一个可执行文件在执行时删除自己IN_MOVE_SELF,自移动,即一个可执行文件在执行时移动自己IN_UNMOUNT, 宿主文件系统被 umountIN_CLOSE,文件被关闭,等同于(IN_CLOSE_WRITE | IN_CLOSE_NOWRITE)IN_MOVE,文件被移动,等同于(IN_MOVED_FROM | IN_MOVED_TO)2、 优点优点1:inotify不打开目标对象描述符,所以目标umount时不影响,且会产生一个umount事件通知inotify机 制,inotify自动删除该监视。优点2:inotify既可以监视文件,也可以监视目录。优点3:inotify使用系统调 用而不是信号的方式来通知文件系统事件,效率应该比较高。优点4:inotify中的添加监视后产生的是新的文件描述符作为接口,因此可以通 过select和poll来监视文件系统的变化。3、应用例子:

view plaincopy to clipboardprint?

    #include<stdio.h>#include<stdlib.h>#include<string.h>#include<linux/unistd.h>#include<linux/inotify.h>char*event_array[]={"Filewasaccessed","Filewasmodified","Fileattributeswerechanged","writtablefileclosed","Unwrittablefileclosed","Filewasopened","FilewasmovedfromX","FilewasmovedtoY","Subfilewascreated","Subfilewasdeleted","Selfwasdeleted","Selfwasmoved","","Backingfswasunmounted","Eventqueuedoverflowed","Filewasignored"};#defineEVENT_NUM16#defineMAX_BUF_SIZE1024intmain(intargc,char*argv[]){intfd,wd;charbuffer[MAX_BUF_SIZE+1];char*offset=NULL;structinotify_event*event;inti,len,tmp_len;charstrbuf[16];if(argc!=2){printf("%sfile|folder\n",argv[0]);exit(0);}if((fd=inotify_init())<0){printf("Failtoinitializeinotify.\n");exit(0);}if((wd=inotify_add_watch(fd,argv[1],IN_ALL_EVENTS))<0){printf("Can’taddwatchfor%s.\n",argv[1]);exit(0);}while(len=read(fd,buffer,MAX_BUF_SIZE)){offset=buffer;event=(structinotify_event*)buffer;while(((char*)event-buffer)<len){printf("Objecttype:%s\n",event->mask&IN_ISDIR?"Direcotory":"File");if(event->wd!=wd)continue;printf("Objectname:%s\n",event->name);printf("Eventmask:%08X\n",event->mask);for(i=0;i<EVENT_NUM;i++){if(event_array[i][0]==’\0′)continue;if(event->mask&(1<<i)){printf("Event:%s\n",event_array[i]);}}tmp_len=sizeof(structinotify_event)+event->len;event=(structinotify_event*)(offset+tmp_len);offset+=tmp_len;}}}

人生没有彩排,只有现场直播,所以每一件事都要努力做得最好

转一篇文章,linux文件访问notify机制 (2011-03-11 18:08)

相关文章:

你感兴趣的文章:

标签云: