在描述之前,要说明一下,我代码中的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_cnt) { /* Parse events and queue them. */ struct inotify_event* pevent = (struct inotify_event*)&buffer[buffer_i]; if (pevent->mask & IN_MODIFY) { printf("config %s modified\n", kszConfigPath); reparse_config(); } else { printf("Unrecognized event mask %d\n", pevent->mask); } buffer_i += sizeof(struct inotify_event) + pevent->len; } } /** Remove watch. */ if (inotify_rm_watch(inot_fd, watch_fd) < 0) { printf("inotify_rm_watch error %d\n", errno); } return 0; }一、使用vi编辑a文件,然后保存。程序没有截获IN_MODIFY事件,打印的是Unrecongnized event mask 32768。
#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(); #ifdef _WIN32 struct inotify_event { int wd; /* Watch descriptor */ uint32_t mask; /* Mask of events */ uint32_t cookie; /* Unique cookie associating related events (for rename(2)) */ uint32_t len; /* Size of name field */ char name[]; /* Optional null-terminated name */ }; int inotify_init(void); int inotify_add_watch(int fd, const char *pathname, uint32_t mask); int inotify_rm_watch(int fd, int wd); #endif int set_non_blocking(fd) { int fd_flag = 0; if (fd < 0) return EINVAL; fd_flag = fcntl(fd, F_GETFL, 0); if (fd_flag < 0) fd_flag = 0; return fcntl(fd, F_SETFL, fd_flag | O_NONBLOCK); } int rm_inotify_wd(int fd, int wd) { char ignore[1024]; if (fd < 0 || wd < 0) return EINVAL; while (read(fd, ignore) > 0) { /* Ignore previous unread notify events. */ continue; } return inotify_rm_watch(fd, wd); } int inotify_loop() { int selret = 0; int read_cnt = 0; int inot_fd = -1; int watch_fd = -1; int need_parse = 0; int need_remove_wd = 0; unsigned int watch_flag = IN_CLOSE_WRITE | IN_CREATE | IN_DELETE | IN_DELETE_SELF | IN_MOVE | IN_MOVE_SELF; fd_set read_fds; struct timeval seltime; char buffer[16384]; int buffer_i = 0; if ((inot_fd = inotify_init()) < 0) { printf("inotify_init error %d\n", errno); return -1; } if (set_non_blocking(inot_fd) < 0) { printf("set_non_blocking error %d\n", errno); } while (s_running) { new_init= 0; if (watch_fd < 0) { /* Watch config file. */ if ((watch_fd = inotify_add_watch(inot_fd, kszConfigPath, watch_flag)) < 0) { printf("inotify_init error %d\n", errno); } else { /* Non-existed -> existed, reparse immediately.*/ reparse_config(); } } seltime.tv_sec = 1; seltime.tv_usec = 0; if (watch_fd < 0) { selret = select(NULL, NULL, NULL, NULL, &seltime); } else { FD_ZERO(&read_fds); FD_SET(inot_fd, &read_fds); 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; } need_parse = 0; need_remove_wd = 0; buffer_i = 0; while (buffer_i < read_cnt) { /* Parse events and queue them. */ struct inotify_event* pevent = (struct inotify_event*)&buffer[buffer_i]; if (pevent->mask & IN_MODIFY) { printf("config %s modified\n", kszConfigPath); } else if (pevent->mask & IN_CLOSE_WRITE) { printf("config %s close for writing\n", kszConfigPath); need_parse = 1; } else if (pevent->mask & IN_CREATE) { printf("config %s created\n", kszConfigPath); need_parse = 1; } else if (pevent->mask & (IN_DELETE | IN_DELETE_SELF)) { printf("config %s was deleted\n", kszConfigPath); need_parse = 1; need_remove_wd = 1; } else if (pevent->mask & (IN_MOVE | IN_MOVE_SELF)) { printf("config %s was removed\n", kszConfigPath); need_parse = 1; need_remove_wd = 1; } else { printf("Unrecognized event mask %d\n", pevent->mask); } buffer_i += sizeof(struct inotify_event) + pevent->len; } if (need_parse) { reparse_config(); } if (need_remove_wd) { int ret = rm_inotify_wd(inot_fd, watch_fd); if (ret < 0) { printf("rm_inotify_wd error %d\n", ret); } watch_fd = -1; } } /** Remove watch. */ if (inotify_rm_watch(inot_fd, watch_fd) < 0) { printf("inotify_rm_watch error %d\n", errno); } close(inot_fd); return 0; }
原文:http://blog.csdn.net/cool_way/article/details/22827433