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 modified\n", event->name);
break;
}
if(event->wd == inotify.wd2){
printf("Pathname2 '%s' is modified\n", 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);
}
Some remarks:
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 = %d\n", inotify.wd1);
inotify.wd2 = inotify_add_watch(inotify.fd, pathname2, IN_MODIFY);
printf("wd2 = %d\n", inotify.wd2);
while(1){
inotify.length = read(inotify.fd, inotify.buffer, EVENT_BUF_LEN);
int i = 0;
printf("read() = %d\n", inotify.length);
while(i < inotify.length){
struct inotify_event *event = (struct inotify_event *)&inotify.buffer[i];
printf("event->len = %u\n", event->len);
if(event->mask & IN_MODIFY){
if(event->wd == inotify.wd1){
printf("Pathname1 is modified\n");
} else if (event->wd == inotify.wd2){
printf("Pathname2 is modified\n");
}
}
i += (EVENT_SIZE + event->len);
printf("i=%d\n", 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