linux - 使用 inotify 检测文件移动时出现问题。

标签 linux inotify

我想使用 inotify 来监控目录的内容。在我尝试使用 mv 命令重命名目录中的文件之前,一切似乎都很好。我按预期获得了 IN_MOVED_FROM,但没有出现 IN_MOVED_TO。

下面是我的测试程序。编译:

g++ -Wall -o test test.cpp

启动:

./test dir_to_watch
#include <cstdio>
#include <cstring>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/inotify.h>

int main (int argc, char *argv[])
{
  int inotify_fd = inotify_init();

  if (inotify_fd < 0)
  {
    fprintf(stderr, "Unable to init inotify: %m\n");
    return 1;
  }

  int watch_descriptor = inotify_add_watch(inotify_fd,
                       argv[1],
                       IN_ALL_EVENTS);

  if (watch_descriptor < 0)
  {
    fprintf(stderr, "Unable to add inotify watch: %m\n");
    return 1;
  }

  union
  {
    inotify_event event;
    char pad[1024];
  }
  buffer;

  struct events
  {
    int mask;
    const char *name;
  }
  events[] =
  {
    {IN_ACCESS         , "IN_ACCESS        "}, 
    {IN_ATTRIB         , "IN_ATTRIB        "}, 
    {IN_CLOSE_WRITE    , "IN_CLOSE_WRITE   "}, 
    {IN_CLOSE_NOWRITE  , "IN_CLOSE_NOWRITE "}, 
    {IN_CREATE         , "IN_CREATE        "}, 
    {IN_DELETE         , "IN_DELETE        "}, 
    {IN_DELETE_SELF    , "IN_DELETE_SELF   "}, 
    {IN_MODIFY         , "IN_MODIFY        "}, 
    {IN_MOVE_SELF      , "IN_MOVE_SELF     "}, 
    {IN_MOVED_FROM     , "IN_MOVED_FROM    "}, 
    {IN_MOVED_TO       , "IN_MOVED_TO      "}, 
    {IN_OPEN           , "IN_OPEN          "}, 
  };

  while (read(inotify_fd, &buffer, sizeof buffer) > 0)
  {
    for (unsigned i = 0; i < sizeof events / sizeof events[0]; i++)
    {
      if (events[i].mask & buffer.event.mask)
      {
    if (buffer.event.len)
    {
      printf("Inotify %s: %s\n", events[i].name, buffer.event.name);
    }
    else
    {
      printf("Inotify %s\n", events[i].name);
    }
      }
    }
  }
}

最佳答案

自行解决:事实证明,inotify 可以在单个 read() 调用中返回多个事件。所以更正后的源代码如下所示:

#include <cstdio>
#include <cstring>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/inotify.h>

int main (int argc, char *argv[])
{
  int inotify_fd = inotify_init();

  if (inotify_fd < 0)
  {
    fprintf(stderr, "Unable to init inotify: %m\n");
    return 1;
  }

  int watch_descriptor = inotify_add_watch(inotify_fd,
                       argv[1],
                       IN_ALL_EVENTS);

  if (watch_descriptor < 0)
  {
    fprintf(stderr, "Unable to add inotify watch: %m\n");
    return 1;
  }

  struct events
  {
    int mask;
    const char *name;
  }
  events[] =
  {
    {IN_ACCESS         , "IN_ACCESS        "}, 
    {IN_ATTRIB         , "IN_ATTRIB        "}, 
    {IN_CLOSE_WRITE    , "IN_CLOSE_WRITE   "}, 
    {IN_CLOSE_NOWRITE  , "IN_CLOSE_NOWRITE "}, 
    {IN_CREATE         , "IN_CREATE        "}, 
    {IN_DELETE         , "IN_DELETE        "}, 
    {IN_DELETE_SELF    , "IN_DELETE_SELF   "}, 
    {IN_MODIFY         , "IN_MODIFY        "}, 
    {IN_MOVE_SELF      , "IN_MOVE_SELF     "}, 
    {IN_MOVED_FROM     , "IN_MOVED_FROM    "}, 
    {IN_MOVED_TO       , "IN_MOVED_TO      "}, 
    {IN_OPEN           , "IN_OPEN          "}, 
  };

  ssize_t rd;
  char buffer[1024];

  while ((rd = read(inotify_fd, buffer, sizeof buffer)) > 0)
  {
    for (char *ptr = buffer; ptr != buffer + rd; ptr += sizeof(inotify_event) + reinterpret_cast<inotify_event*>(ptr)->len)
    {
      inotify_event *event = reinterpret_cast<inotify_event*>(ptr);

      for (unsigned i = 0; i < sizeof events / sizeof events[0]; i++)
      {
    if (events[i].mask & event->mask)
    {
      if (event->len)
      {
        printf("Inotify %d %s: %s\n", inotify_fd, events[i].name, event->name);
      }
      else
      {
        printf("Inotify %d %s\n", inotify_fd, events[i].name);
      }
    }
      }
    }
  }

  if (rd < 0)
  {
    fprintf(stderr, "inotify read %d event error: %m\n", inotify_fd);
    return 1;
  }
}

关于linux - 使用 inotify 检测文件移动时出现问题。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6211799/

相关文章:

c++ - 使用 dlib 库编译

linux - Linux显卡确定KMS

c - 在 Linux 中保护文件不被编辑

c++ - 适用于 Linux 的良好 C++ 调试/IDE 环境?

linux - Bash - 比较 2 个文件列表及其 md5 校验和

c - 使用 inotify 检测外部 IN_MOVED_FROM 重命名

c - 如何在 C 中使用 inotify?

linux - 监视新文件目录的 bash 脚本

linux - iNotify 能否告诉我受监控的文件移动到了哪里?

c - linux 是否允许从信号处理程序进行任何系统调用?