inotify还是不错的,玩着似乎很简单,但是坑也不少,如果不仔细查看官方文档,可能就真的不知道哪里存在坑,哪里需要注意。前段时间,在项目中使用inotify监控配置文件,以达到实时感知配置改变的目的。但近日查看线上日志发现,配置文件改变后,inotify并没有通知,结果导致配置一直未被更改。
在描述之前,要说明一下,我代码中的inotify使用方式,这个方式和网上大多方式一样:
#include <errno.h>
#include <stdio.h>
#include <sys/inotify.h>
static const char kszConfigPath[] = "/usr/local/path/to/config";
static int s_running = 0;
extern int reparse_config();
int inotify_loop()
{
int inot_fd = -1;
int watch_fd = -1;
unsigned int watch_flag = IN_MODIFY;
fd_set read_fds;
struct timeval seltime;
char buffer[16384];
int buffer_i = 0;
int inot_fd = inotify_init();
if (inot_fd < 0) {
printf("inotify_init error %d\n", errno);
return -1;
}
/* Watch config file. */
watch_fd = inotify_add_watch(inot_fd, kszConfigPath, watch_flag);
if (watch_fd < 0) {
printf("inotify_init error %d\n", errno);
close(inot_fd);
return -1;
}
while (s_running) {
int selret = 0;
int read_cnt = 0;
FD_ZERO(&read_fds);
FD_SET(inot_fd, &read_fds);
seltime.tv_sec = 1;
seltime.tv_usec = 0;
selret = select(inot_fd + 1, &read_fds, NULL, NULL, &seltime);
if (selret < 0) {
printf("select error %d\n", errno);
continue;
} else if (selret == 0) {
continue;
}else if (!FD_ISSET(inot_fd, &read_fds)) {
printf("inot_fd not in fdset\n");
continue;
}
read_cnt = read(fd, buffer, sizeof(buffer));
if (read_cnt <= 0) {
printf("read <= 0 (%d)\n", read_cnt);
continue;
}
buffer_i = 0;
while (buffer_i < read