I am using inotify to listen to modifications to a file.
When I test file modification, program is working fine.
# echo "test" > /tftpboot/.TEST
Output:
Read 16 data
IN_MODIFY
But when I do tftp put, two events are generated:
tftp> put .TEST
Sent 6 bytes in 0.1 seconds
tftp>
Output:
Read 16 data
IN_MODIFY
Read 16 data
IN_MODIFY
Any idea how to avoid the duplicate notification?
Code is given below:
#include <sys/inotify.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <iostream>
using namespace std;
int main(int argc, const char *argv[])
{
int fd = inotify_init();
if (fd < 0)
{
cout << "inotify_init failed\n";
return 1;
}
int wd = inotify_add_watch(fd, "/tftpboot/.TEST", IN_MODIFY);
if (wd < 0)
{
cout << "inotify_add_watch failed\n";
return 1;
}
while (true)
{
char buffer[sizeof(struct inotify_event) + NAME_MAX + 1] = {0};
ssize_t length;
do
{
length = read( fd, buffer, sizeof(struct inotify_event));
cout << "Read " << length << " data\n";
}while (length < 0);
if (length < 0)
{
cout << "read failed\n";
return 1;
}
struct inotify_event *event = ( struct inotify_event * ) buffer;
if ( event->mask & IN_ACCESS )
cout << "IN_ACCESS\n";
if ( event->mask & IN_CLOSE_WRITE )
cout << "IN_CLOSE_WRITE\n";
if ( event->mask & IN_CLOSE_NOWRITE )
cout << "IN_CLOSE_NOWRITE\n";
if ( event->mask & IN_MODIFY )
cout << "IN_MODIFY \n";
if ( event->mask & IN_OPEN )
cout << "IN_OPEN\n";
}
inotify_rm_watch( fd, wd );
close (fd);
return 0;
}
try using IN_CLOSE_WRITE
instead
Q: What is the difference between IN_MODIFY and IN_CLOSE_WRITE?
The IN_MODIFY event is emitted on a file content change (e.g. via the write() syscall) while IN_CLOSE_WRITE occurs on closing the changed file. It means each change operation causes one IN_MODIFY event (it may occur many times during manipulations with an open file) whereas IN_CLOSE_WRITE is emitted only once (on closing the file).
Q: Is it better to use IN_MODIFY or IN_CLOSE_WRITE?
It varies from case to case. Usually it is more suitable to use IN_CLOSE_WRITE because if emitted the all changes on the appropriate file are safely written inside the file. The IN_MODIFY event needn't mean that a file change is finished (data may remain in memory buffers in the application). On the other hand, many logs and similar files must be monitored using IN_MODIFY - in such cases where these files are permanently open and thus no IN_CLOSE_WRITE can be emitted.