In this code, I am trying to monitor two paths at the same time. I used while(1)
for this purpose. But the problem that I am facing is that whenever I run the code, it gives me the same result two times like this.
Giving result
Pathname1 "file" is modified Pathname1 "file" is modified
Expected result
Pathname1 "file" is modified
I debugged the code. After breaking the main function and stepping over it, the next command stops at this line length = read(fd, buffer, EVENT_BUF_LEN )
. Whenever I break a line after this length variable command, the program starts and after modifying the file, the program stops at this line struct inotify_event *event = ( struct inotify_event *)&buffer[i];
Although the program should not break.
I also used IN_CLOSE_WRITE
instead of IN_MODIFY
but no change in the result.
typedef struct{ int length, fd, wd1, wd2; char buffer[4096] __attribute__ ((aligned(__alignof__(struct inotify_event)))); } notification; notification inotify; int getNotified(char *pathname1, char *pathname2){ inotify.fd = inotify_init(); inotify.wd1 = inotify_add_watch(inotify.fd, pathname1, IN_MODIFY); inotify.wd2 = inotify_add_watch(inotify.fd, pathname2, IN_MODIFY); while(1){ inotify.length = read(inotify.fd, inotify.buffer, EVENT_BUF_LEN); int i = 0; while(i < inotify.length){ struct inotify_event *event = (struct inotify_event *)&inotify.buffer[i]; if(event->len){ if(event->mask & IN_MODIFY){ if(event->wd == inotify.wd1){ printf("Pathname1 '%s' is modifiedn", event->name); break; } if(event->wd == inotify.wd2){ printf("Pathname2 '%s' is modifiedn", event->name); break; } } } i += EVENT_SIZE + event->len; } } inotify_rm_watch(inotify.fd, inotify.wd1); inotify_rm_watch(inotify.fd, inotify.wd2); close(inotify.fd); exit(0); }
Advertisement
Answer
Some remarks:
- You should not “break” as you go out of the inside “while” loop and call read() again
- The IN_MODIFY event does not fill the event->name field (i.e. event->len = 0)
- The number of IN_MODIFY events depends on how you modify the files (“echo xxx >> file” = write only = 1 IN_MODIFY; “echo xxx > file” = truncate + write = 2 IN_MODIFY)
Here is a proposition for your program (with additional prints):
#include <stdio.h> #include <sys/inotify.h> #include <unistd.h> #include <stdlib.h> #define EVENT_BUF_LEN 4096 #define EVENT_SIZE sizeof(struct inotify_event) typedef struct{ int length, fd, wd1, wd2; char buffer[EVENT_BUF_LEN] __attribute__ ((aligned(__alignof__(struct inotify_event)))); } notification; notification inotify; int getNotified(char *pathname1, char *pathname2){ inotify.fd = inotify_init(); inotify.wd1 = inotify_add_watch(inotify.fd, pathname1, IN_MODIFY); printf("wd1 = %dn", inotify.wd1); inotify.wd2 = inotify_add_watch(inotify.fd, pathname2, IN_MODIFY); printf("wd2 = %dn", inotify.wd2); while(1){ inotify.length = read(inotify.fd, inotify.buffer, EVENT_BUF_LEN); int i = 0; printf("read() = %dn", inotify.length); while(i < inotify.length){ struct inotify_event *event = (struct inotify_event *)&inotify.buffer[i]; printf("event->len = %un", event->len); if(event->mask & IN_MODIFY){ if(event->wd == inotify.wd1){ printf("Pathname1 is modifiedn"); } else if (event->wd == inotify.wd2){ printf("Pathname2 is modifiedn"); } } i += (EVENT_SIZE + event->len); printf("i=%dn", i); } } inotify_rm_watch(inotify.fd, inotify.wd1); inotify_rm_watch(inotify.fd, inotify.wd2); close(inotify.fd); exit(0); } int main(void) { getNotified("/tmp/foo", "/tmp/bar"); return 0; } // main
Here is an example of execution:
$ gcc notif.c -o notif $ > /tmp/foo $ > /tmp/bar $ ./notif wd1 = 1 wd2 = 2 ====== Upon "> /tmp/foo": 1 event (truncate operation) read() = 16 event->len = 0 Pathname1 is modified i=16 ====== Upon "echo qwerty > /tmp/foo": 2 events (write operation, one event for truncate operation and one for the write of "qwerty" at the beginning of the file) read() = 16 event->len = 0 Pathname1 is modified i=16 read() = 16 event->len = 0 Pathname1 is modified i=16 ====== Upon "echo qwerty >> /tmp/foo": 1 event (write of "qwerty" at the end of the file) read() = 16 event->len = 0 Pathname1 is modified i=16