9

I am using inotify to monitor a local file, for example "/root/temp" using

inotify_add_watch(fd, "/root/temp", mask).

When this file is deleted, the program will be blocked by read(fd, buf, bufSize) function. Even if I create a new "/root/temp" file, the program is still block by read function. I am wondering if inotify can detect that the monitored file is created and the read function can get something from fd so that read will not be blocked forever. Here is my code:

uint32_t mask = IN_ALL_EVENTS;
int fd = inotify_init();
int wd = inotify_add_watch(fd, "/root/temp", mask);
char *buf = new char[1000];
int nbytes = read(fd, buf, 500);

I monitored all events.

iehrlich
  • 3,572
  • 4
  • 34
  • 43
user572138
  • 463
  • 4
  • 6
  • 13

2 Answers2

22

The problem is that read is a blocking operation by default.

If you don't want it to block, use select or poll before read. For example:

struct pollfd pfd = { fd, POLLIN, 0 };
int ret = poll(&pfd, 1, 50);  // timeout of 50ms
if (ret < 0) {
    fprintf(stderr, "poll failed: %s\n", strerror(errno));
} else if (ret == 0) {
    // Timeout with no events, move on.
} else {
    // Process the new event.
    struct inotify_event event;
    int nbytes = read(fd, &event, sizeof(event));
    // Do what you need...
}

Note: untested code.

jweyrich
  • 31,198
  • 5
  • 66
  • 97
  • If I use select or poll, do I need to periodically check the file, for example while (true) {select(...); sleep();}? What I want is the changes to the file should be pushed to me. If no changes happen, the program shold be blocked like read function. – user572138 Jan 12 '11 at 03:35
  • 1
    @user572138: the snippet I provided does: 1) Wait for a new event for 50ms; 2) If no event is received during this time, it does nothing; 3) If a new event is received, it reads the event; - To get the behaviour you described, you just need to wrap it in a loop, like you mentioned. – jweyrich Jan 12 '11 at 03:45
  • I might had misunderstood your first post, I know what you mean now. I think this is a good solution, thanks. – user572138 Jan 12 '11 at 03:46
  • 1
    @user572138: I'm glad it helped. I encourage you to read about the [reputation system](http://stackoverflow.com/faq#reputation) in the [FAQ](http://stackoverflow.com/faq), if you haven't yet. – jweyrich Jan 12 '11 at 04:23
3

In order to see a new file created, you need to watch the directory, not the file. Watching a file should see when it is deleted (IN_DELETE_SELF) but may not spot if a new file is created with the same name.

You should probably watch the directory for IN_CREATE | IN_MOVED_TO to see newly created files (or files moved in from another place).

Some editors and other tools (e.g. rsync) may create a file under a different name, then rename it.

MarkR
  • 62,604
  • 14
  • 116
  • 151