首页 > 解决方案 > 什么是用于监视写入文件的正确 inotify 事件掩码配置?

问题描述

我正在尝试使用 inotify 来监视文件的任何读取或写入。

典型的用例是用户运行以下命令之一,我收到相应的通知。

echo "xyz" > /tmp/the_file# 这应该给我一个写通知

或者

cat /tmp/the_file# 这应该会给我一个访问通知。

我试过以下面具:

为每次读取和写入获取单个通知的正确掩码值是多少?

我正在使用此博客中的测试应用程序作为参考: 如何在 C 语言中使用 inotify API

#include<stdio.h>
#include<sys/inotify.h>
#include<unistd.h>
#include<stdlib.h>
#include<signal.h>
#include<fcntl.h>

#define MAX_EVENTS 1024
#define LEN_NAME 256
#define EVENT_SIZE  (sizeof (struct inotify_event))
#define BUF_LEN     (MAX_EVENTS * (EVENT_SIZE + LEN_NAME))

int fd,wd;
void sig_handler(int sig){
  inotify_rm_watch(fd, wd);
  close(fd);
  exit(0);
}

int main(int argc, char **argv){
  char *path_to_be_watched;
  int i=0,length;
  char buffer[BUF_LEN];
  struct inotify_event *event = (struct inotify_event *) &buffer[i];

  path_to_be_watched = argv[1];
  signal(SIGINT,sig_handler);
  fd = inotify_init();
  fcntl(fd, F_SETFL, O_NONBLOCK);
  wd = inotify_add_watch(fd, path_to_be_watched, IN_MODIFY | IN_ACCESS);

  if(wd==-1){
    printf("Could not watch : %s\n", path_to_be_watched);
  } else {
    printf("Watching : %s\n", path_to_be_watched);
  }

  while(1){
    i=0;
    length = read(fd,buffer,BUF_LEN);

    while(i<length){
      event = (struct inotify_event *) &buffer[i];

      if(event->len){
        if ( event->mask & IN_MODIFY ) {
          printf( "The file %s was modified.\n", event->name );
          /* This gets printed twice when I run 'echo "123" > /tmp/this_file' */
        }
        else if ( event->mask & IN_ACCESS ) {
          printf( "The file %s was accessed.\n", event->name );
        }
      }
      i += EVENT_SIZE + event->len;
    }
  }

  return(0);
}

strace 的片段echo "hello" > ./a.txt

openat(AT_FDCWD, "./a.txt", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 3
fcntl64(1, F_GETFD)                     = 0
fcntl64(1, F_DUPFD, 10)                 = 10
fcntl64(1, F_GETFD)                     = 0
fcntl64(10, F_SETFD, FD_CLOEXEC)        = 0
dup2(3, 1)                              = 1
close(3)                                = 0
write(1, "hello\n", 6)                  = 6
dup2(10, 1)                             = 1
fcntl64(10, F_GETFD)                    = 0x1 (flags FD_CLOEXEC)
close(10)                               = 0

标签: linuxembedded-linuxinotify

解决方案


推荐阅读