=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_EVENTSstruct inotify_data_type{ int fd; char self_type[16];};#ifndef PATH_MAX#define PATH_MAX 128#endiftypedef 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