=Start=
缘由:
学习、提高需要
正文:
参考解答:
#include <sys/inotify.h> #include <sys/epoll.h> #include <stdlib.h> #include <stdio.h> #include <sys/ioctl.h> #include <string.h> #define MONITOR_FLAGS IN_MOVED_FROM|IN_MOVED_TO|IN_CREATE|IN_MODIFY|IN_ATTRIB|IN_DELETE|IN_DELETE_SELF // #define MONITOR_FLAGS IN_ALL_EVENTS struct inotify_data_type{ int fd; char self_type[ 16 ]; }; #ifndef PATH_MAX #define PATH_MAX 128 #endif typedef struct { int fd; char pathname[PATH_MAX]; } inotify_fd_path; int main( int argc, char * argv[]){ if (argc < 2 ) { return 1 ; } int inotify_fd = inotify_init(); if (inotify_fd < 0 ){ printf( "inotify_init() error, create inotify descriptor failed." ); return 1 ; } inotify_fd_path *wd_arr = malloc(sizeof(inotify_fd_path)*(argc- 1 )); int i; for (i = 1 ; i < argc; i++){ wd_arr[i- 1 ].fd = inotify_add_watch(inotify_fd, argv[i], MONITOR_FLAGS); strncpy(wd_arr[i- 1 ].pathname, argv[i], PATH_MAX- 1 ); if (wd_arr[i- 1 ].fd < 0 ){ printf( "inotify_add_watch() error, could not watch dirctory : %s" ); return 1 ; } } int nb = 1 ; ioctl(inotify_fd, FIONBIO, &nb); // 作用是? int epoll_fd = epoll_create( 1024 ); if (epoll_fd < 0 ){ printf( "epoll_create() error, create epoll descriptor failed" ); return 1 ; } struct inotify_data_type inotify_data; inotify_data.fd = inotify_fd; strcpy(inotify_data.self_type, "inotify" ); struct epoll_event inotify_event; int option = EPOLL_CTL_ADD; inotify_event.events = EPOLLIN|EPOLLET; inotify_event.data.ptr = &inotify_data; int result = epoll_ctl(epoll_fd, option, inotify_fd, &inotify_event); if (result < 0 ){ printf( "epoll_ctl() error, could not add Inotify event in EPOLL" ); return 1 ; } int running = 1 ; struct epoll_event event_list[ 10 ]; while (running){ int events_num = epoll_wait(epoll_fd, event_list, 10 , 0 ); if (events_num < 0 ){ printf( "epoll_wait() failed" ); return 1 ; } if (events_num > 0 ){ // int i = 0; for (i = 0 ; i < events_num; i++){ struct inotify_data_type *inotify_data_backup = event_list[i].data.ptr; if (strcmp(inotify_data_backup->self_type, "inotify" ) == 0 ){ int revents = event_list[i].events; if (revents & (EPOLLERR|EPOLLHUP)){ continue ; } if (revents & EPOLLIN){ char inotify_event_buf[ 1024 ]; bzero(inotify_event_buf, 1024 ); int length = read(inotify_data_backup->fd, inotify_event_buf, 1024 ); // 理论上,下面的代码不需要使用循环 char *tmp; int tmp_len; for (tmp = inotify_event_buf, tmp_len = 0 ; (tmp-inotify_event_buf) < length; tmp += tmp_len){ struct inotify_event *iev = (struct inotify_event*)tmp; int j = 0 ; for (j = 0 ; j < argc- 1 ; j++){ if (wd_arr[j].fd == iev->wd){ // 这里的 iev->name 只有文件名,不是全文件名 if (iev->mask & IN_ACCESS){ printf( "[IN_ACCESS]The inotify event fd(%d) referred to File=%s, whose pathname=%s\n" , wd_arr[j].fd, iev->name, wd_arr[j].pathname); } if (iev->mask & IN_ATTRIB){ printf( "[IN_ATTRIB]The inotify event fd(%d) referred to File=%s, whose pathname=%s\n" , wd_arr[j].fd, iev->name, wd_arr[j].pathname); } if (iev->mask & IN_CLOSE_WRITE){ printf( "[IN_CLOSE_WRITE]The inotify event fd(%d) referred to File=%s, whose pathname=%s\n" , wd_arr[j].fd, iev->name, wd_arr[j].pathname); } if (iev->mask & IN_CREATE){ printf( "[IN_CREATE]The inotify event fd(%d) referred to File=%s, whose pathname=%s\n" , wd_arr[j].fd, iev->name, wd_arr[j].pathname); } if (iev->mask & IN_MODIFY){ printf( "[IN_MODIFY]The inotify event fd(%d) referred to File=%s, whose pathname=%s\n" , wd_arr[j].fd, iev->name, wd_arr[j].pathname); } if (iev->mask & IN_DELETE){ printf( "[IN_DELETE]The inotify event fd(%d) referred to File=%s, whose pathname=%s\n" , wd_arr[j].fd, iev->name, wd_arr[j].pathname); } } } tmp_len = sizeof(struct inotify_event)+iev->len; } } } } } } close(epoll_fd); return 0 ; } |
参考链接:
Difference between inotify and epoll
https://stackoverflow.com/questions/17207809/difference-between-inotify-and-epoll
epoll模型添加inotify事件的代码实现
http://blog.csdn.net/zhoushuaiyin/article/details/42639053
使用epoll + inotify监控文件
http://xinmingyao.iteye.com/blog/705984
Like `tail -F` but with more epoll and inotify
https://github.com/Roguelazer/einotail
=END=
《 “Linux下的epoll和inotify” 》 有 3 条评论
http://man7.org/linux/man-pages/man7/inotify.7.html
http://man7.org/linux/man-pages/man7/epoll.7.html
`
inotify_init();
inotify_add_watch(); // the 3rd argument
epoll_create();
epoll_ctl();
epoll_wait();
while {
read() & process( inotify_event );
}
`
Linux完整性保护机制模块
https://mp.weixin.qq.com/s/pTEPhcAfafsdA7zHB4IuVg
Linux完整性保护机制模块总体描述(2)
https://mp.weixin.qq.com/s/PsyK0y-Slys_0wqx5wvt0Q
`
在内核中的dnotify,inotify(Linux 2.6.26+)以及fanotify(Linux 2.6.36+)三种监视机制都是基于fsnotify实现的一种通知策略,fsnotify则实现了文件状态通知的框架。
`
fanotify 监控文件系统(inotify 的替代)
https://www.ibm.com/developerworks/cn/linux/l-cn-fanotify/index.html
http://man7.org/linux/man-pages/man7/fanotify.7.html
http://manpages.ubuntu.com/manpages/zesty/man7/fanotify.7.html
How do I program for Linux’s new `fanotify` file system monitoring feature?
https://stackoverflow.com/questions/1835947/how-do-i-program-for-linuxs-new-fanotify-file-system-monitoring-feature
How to tell which path a fanotify event refers to
https://stackoverflow.com/questions/13379632/how-to-tell-which-path-a-fanotify-event-refers-to
fanotify: the fscking all notification system
https://lwn.net/Articles/339253/
用Golang写的跨平台文件系统监控机制(Cross-platform file system notifications for Go.)
https://github.com/fsnotify/fsnotify
Sophos Anti-Virus for Linux: Fanotify Overview
https://community.sophos.com/kb/en-us/118216
A simple fanotify example for watching events on a filesystem.
https://github.com/NegativeMjark/fanotify
Is fanotify supported in Red Hat Enterprise Linux?
https://access.redhat.com/solutions/458193