diff --git a/inotify/show_events.c b/inotify/show_events.c index 16ea210..aeda69b 100644 --- a/inotify/show_events.c +++ b/inotify/show_events.c @@ -4,7 +4,7 @@ * * 20201130 @miura added #include to prevent warning of implicit declaration of functions: * read / close. -*/ + */ #include #include #include @@ -16,273 +16,273 @@ // @miura added #include #include - + #define WATCH_DIR "." - + //イベントサイズは16バイト境界 #define INOTIFY_EVENT_MAX (((sizeof(struct inotify_event)+NAME_MAX+1)+16)&~16) - + typedef struct _WD_INFO { - struct _WD_INFO* prev; - struct _WD_INFO* next; - int wd; - char* path; + struct _WD_INFO* prev; + struct _WD_INFO* next; + int wd; + char* path; } WD_INFO; - + static WD_INFO* topWdInfo = NULL; - + static void getWdInfo(int fd, char* dirname) { - DIR* dir = NULL; - struct dirent* entry; - struct stat st; - int wd; - int dirname_len; - int entname_len; - char* fullpath = NULL; - WD_INFO* newWdInfo; - - newWdInfo = (WD_INFO*)malloc(sizeof(WD_INFO)); - - if(topWdInfo == NULL){ - // first - topWdInfo = newWdInfo; - topWdInfo->prev = topWdInfo; - topWdInfo->next = topWdInfo; - }else{ - newWdInfo->prev = topWdInfo->prev; - topWdInfo->prev->next = newWdInfo; - topWdInfo->prev = newWdInfo; - newWdInfo->next = topWdInfo; - } - - newWdInfo->wd = inotify_add_watch(fd, dirname, IN_ALL_EVENTS); - newWdInfo->path = strdup(dirname); - - //Search Sub directry - dir = opendir(dirname); - - dirname_len = strlen(dirname); - - while((entry = readdir(dir)) != NULL){ - - if(strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0){ - continue; - } - - //エントリのタイプ種別を非標準のd_typeを使わず、statで取得 - entname_len = strlen(entry->d_name); - fullpath = (char*)malloc(dirname_len + 1 + entname_len + 1); - strcpy(fullpath, dirname); - strcat(fullpath, "/"); - strcat(fullpath, entry->d_name); - stat(fullpath, &st); - - if(S_ISDIR(st.st_mode)){ - //再帰呼び出し - getWdInfo(fd, fullpath); - } - - free(fullpath); - } - - closedir(dir); + DIR* dir = NULL; + struct dirent* entry; + struct stat st; + int wd; + int dirname_len; + int entname_len; + char* fullpath = NULL; + WD_INFO* newWdInfo; + + newWdInfo = (WD_INFO*)malloc(sizeof(WD_INFO)); + + if(topWdInfo == NULL){ + // first + topWdInfo = newWdInfo; + topWdInfo->prev = topWdInfo; + topWdInfo->next = topWdInfo; + }else{ + newWdInfo->prev = topWdInfo->prev; + topWdInfo->prev->next = newWdInfo; + topWdInfo->prev = newWdInfo; + newWdInfo->next = topWdInfo; + } + + newWdInfo->wd = inotify_add_watch(fd, dirname, IN_ALL_EVENTS); + newWdInfo->path = strdup(dirname); + + //Search Sub directry + dir = opendir(dirname); + + dirname_len = strlen(dirname); + + while((entry = readdir(dir)) != NULL){ + + if(strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0){ + continue; + } + + //エントリのタイプ種別を非標準のd_typeを使わず、statで取得 + entname_len = strlen(entry->d_name); + fullpath = (char*)malloc(dirname_len + 1 + entname_len + 1); + strcpy(fullpath, dirname); + strcat(fullpath, "/"); + strcat(fullpath, entry->d_name); + stat(fullpath, &st); + + if(S_ISDIR(st.st_mode)){ + //再帰呼び出し + getWdInfo(fd, fullpath); + } + + free(fullpath); + } + + closedir(dir); } static char* wd2path(int wd) { - WD_INFO* p; - - if(topWdInfo == NULL){ - return NULL; - } - - p = topWdInfo; - do{ - if(p->wd == wd){ - return p->path; - } - p = p->next; - }while(p != topWdInfo); - - return NULL; + WD_INFO* p; + + if(topWdInfo == NULL){ + return NULL; + } + + p = topWdInfo; + do{ + if(p->wd == wd){ + return p->path; + } + p = p->next; + }while(p != topWdInfo); + + return NULL; } - + static void closeAllWdInfo(int fd) { - WD_INFO* p; - - if(topWdInfo == NULL){ - return; - } - - p = topWdInfo; - do{ - WD_INFO* del; - del = p; - p = p->next; - free(del->path); - inotify_rm_watch(fd, del->wd); - free(del); - }while(p != topWdInfo); - topWdInfo = NULL; + WD_INFO* p; + + if(topWdInfo == NULL){ + return; + } + + p = topWdInfo; + do{ + WD_INFO* del; + del = p; + p = p->next; + free(del->path); + inotify_rm_watch(fd, del->wd); + free(del); + }while(p != topWdInfo); + topWdInfo = NULL; } - + static void deleteWdInfo(int wd) { - WD_INFO* p; - - if(topWdInfo == NULL){ - return; - } - - p = topWdInfo; - do{ - if(p->wd == wd){ - if(p->next == p->prev){ - topWdInfo = NULL; - }else{ - if(p == topWdInfo){ - topWdInfo = p->next; - } - p->next->prev = p->prev; - p->prev->next = p->next; - } - free(p->path); - free(p); - + WD_INFO* p; + + if(topWdInfo == NULL){ return; - } - p = p->next; - }while(p != topWdInfo); - - return; + } + + p = topWdInfo; + do{ + if(p->wd == wd){ + if(p->next == p->prev){ + topWdInfo = NULL; + }else{ + if(p == topWdInfo){ + topWdInfo = p->next; + } + p->next->prev = p->prev; + p->prev->next = p->next; + } + free(p->path); + free(p); + + return; + } + p = p->next; + }while(p != topWdInfo); + + return; } /** @miura added */ void print_datetime() { - time_t t = time(NULL); - struct tm *lcl = localtime(&t); - printf("%02d/%02d %02d:%02d:%02d ", lcl->tm_mon+1, lcl->tm_mday, - lcl->tm_hour, lcl->tm_min, lcl->tm_sec); + time_t t = time(NULL); + struct tm *lcl = localtime(&t); + printf("%02d/%02d %02d:%02d:%02d ", lcl->tm_mon+1, lcl->tm_mday, + lcl->tm_hour, lcl->tm_min, lcl->tm_sec); } int main(int argc, char** argv) { - struct timeval waitval; - int fd; - int ret; - fd_set readfds; + struct timeval waitval; + int fd; + int ret; + fd_set readfds; - fd = inotify_init(); + fd = inotify_init(); - getWdInfo(fd, (char*)WATCH_DIR); + getWdInfo(fd, (char*)WATCH_DIR); - while(1){ - FD_ZERO(&readfds); - FD_SET(fd, &readfds); - ret = select(fd+1, &readfds, NULL, NULL, NULL); - if(0 < ret){ - if(FD_ISSET(fd, &readfds)){ - char* buf; - int len; - struct inotify_event* event; + while(1){ + FD_ZERO(&readfds); + FD_SET(fd, &readfds); + ret = select(fd+1, &readfds, NULL, NULL, NULL); + if(0 < ret){ + if(FD_ISSET(fd, &readfds)){ + char* buf; + int len; + struct inotify_event* event; - buf = (char*)malloc(INOTIFY_EVENT_MAX); + buf = (char*)malloc(INOTIFY_EVENT_MAX); - //INOTIFY_EVENT_MAXを指定し、最低でも一つのイベントは読み込む。 - len = read(fd, buf, INOTIFY_EVENT_MAX); + //INOTIFY_EVENT_MAXを指定し、最低でも一つのイベントは読み込む。 + len = read(fd, buf, INOTIFY_EVENT_MAX); - event = (struct inotify_event*)buf; + event = (struct inotify_event*)buf; - //複数イベントがあるかもしれない。全部処理するまでループ。 - while(len > 0){ - char* target; - if(event->len){ - target = event->name; - }else{ - target = wd2path(event->wd); - } + //複数イベントがあるかもしれない。全部処理するまでループ。 + while(len > 0){ + char* target; + if(event->len){ + target = event->name; + }else{ + target = wd2path(event->wd); + } - print_datetime(); + print_datetime(); - if(event->mask & IN_ACCESS){ - printf("[%s] was accessed.\n", target); - } - if(event->mask & IN_MODIFY){ - printf("[%s] was modified.\n", target); - } - if(event->mask & IN_ATTRIB){ - printf("Metadata of [%s] changed.\n", target); - } - if(event->mask & IN_CLOSE_WRITE){ - printf("Writtable [%s] was closed.\n", target); - } - if(event->mask & IN_CLOSE_NOWRITE){ - printf("Unwrittable [%s] closed.\n", target); - } - if(event->mask & IN_OPEN){ - printf("[%s] was opened.\n", target); - } - if(event->mask & IN_MOVED_FROM){ - printf("[%s] was moved from X.\n", target); - } - if(event->mask & IN_MOVED_TO){ - printf("[%s] was moved to Y.\n", target); - } - if(event->mask & IN_CREATE){ - printf("[%s] was created in [%s].\n", event->name, wd2path(event->wd)); - char* dirname; - int dirname_len; - int eventname_len; - char* fullpath; - struct stat st; + if(event->mask & IN_ACCESS){ + printf("[%s] was accessed.\n", target); + } + if(event->mask & IN_MODIFY){ + printf("[%s] was modified.\n", target); + } + if(event->mask & IN_ATTRIB){ + printf("Metadata of [%s] changed.\n", target); + } + if(event->mask & IN_CLOSE_WRITE){ + printf("Writtable [%s] was closed.\n", target); + } + if(event->mask & IN_CLOSE_NOWRITE){ + printf("Unwrittable [%s] closed.\n", target); + } + if(event->mask & IN_OPEN){ + printf("[%s] was opened.\n", target); + } + if(event->mask & IN_MOVED_FROM){ + printf("[%s] was moved from X.\n", target); + } + if(event->mask & IN_MOVED_TO){ + printf("[%s] was moved to Y.\n", target); + } + if(event->mask & IN_CREATE){ + printf("[%s] was created in [%s].\n", event->name, wd2path(event->wd)); + char* dirname; + int dirname_len; + int eventname_len; + char* fullpath; + struct stat st; - dirname = wd2path(event->wd); - eventname_len = strlen(event->name); - fullpath = (char*)malloc(dirname_len + 1 + eventname_len + 1); - strcpy(fullpath, dirname); - strcat(fullpath, "/"); - strcat(fullpath, event->name); - stat(fullpath, &st); + dirname = wd2path(event->wd); + eventname_len = strlen(event->name); + fullpath = (char*)malloc(dirname_len + 1 + eventname_len + 1); + strcpy(fullpath, dirname); + strcat(fullpath, "/"); + strcat(fullpath, event->name); + stat(fullpath, &st); - if(S_ISDIR(st.st_mode)){ - //監視対象追加 - getWdInfo(fd, fullpath); + if(S_ISDIR(st.st_mode)){ + //監視対象追加 + getWdInfo(fd, fullpath); + } + + } + if(event->mask & IN_DELETE){ + printf("[%s] was deleted in [%s].\n", event->name, wd2path(event->wd)); + } + if(event->mask & IN_DELETE_SELF){ + printf("[%s] was deleted.\n", target); + } + if(event->mask & IN_MOVE_SELF){ + printf("[%s] was moved.\n", target); + } + + if(event->mask & IN_IGNORED){ + printf("[%s] was ignored.\n", target); + //監視対象削除 + deleteWdInfo(event->wd); + } + + len -= (sizeof(struct inotify_event) + event->len); + event = (struct inotify_event*)(((char*)event)+sizeof(struct inotify_event) + event->len); } - - } - if(event->mask & IN_DELETE){ - printf("[%s] was deleted in [%s].\n", event->name, wd2path(event->wd)); - } - if(event->mask & IN_DELETE_SELF){ - printf("[%s] was deleted.\n", target); - } - if(event->mask & IN_MOVE_SELF){ - printf("[%s] was moved.\n", target); - } - - if(event->mask & IN_IGNORED){ - printf("[%s] was ignored.\n", target); - //監視対象削除 - deleteWdInfo(event->wd); - } - - len -= (sizeof(struct inotify_event) + event->len); - event = (struct inotify_event*)(((char*)event)+sizeof(struct inotify_event) + event->len); - } - free(buf); + free(buf); + } } - } - } + } - closeAllWdInfo(fd); - close(fd); + closeAllWdInfo(fd); + close(fd); - return 0; + return 0; }