From c6096967e3d8d98f24210d4c66e4d22509bdce5c Mon Sep 17 00:00:00 2001 From: "Dmitrij D. Czarkoff" Date: Mon, 28 Dec 2015 11:33:16 +0100 Subject: Use stat(2) to monitor file changes Makes file monitoring in imv completely POSIX. --- src/main.c | 8 +------- src/navigator.c | 24 ++++++++++++++++++++---- src/navigator.h | 6 +++++- src/reload.c | 49 ------------------------------------------------- src/reload.h | 31 ------------------------------- 5 files changed, 26 insertions(+), 92 deletions(-) delete mode 100644 src/reload.c delete mode 100644 src/reload.h (limited to 'src') diff --git a/src/main.c b/src/main.c index 5bdde7e..6f48fb6 100644 --- a/src/main.c +++ b/src/main.c @@ -28,7 +28,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "navigator.h" #include "viewport.h" #include "util.h" -#include "reload.h" struct { int fullscreen; @@ -285,9 +284,6 @@ int main(int argc, char** argv) struct imv_viewport view; imv_init_viewport(&view, window); - struct imv_reload reload; - imv_init_reload(&reload); - /* put us in fullscren mode to begin with if requested */ if(g_options.fullscreen) { imv_viewport_toggle_fullscreen(&view); @@ -422,7 +418,7 @@ int main(int argc, char** argv) } /* if the user has changed image, start loading the new one */ - if(imv_navigator_poll_changed(&nav) || imv_reload_changed(&reload)) { + if(imv_navigator_poll_changed(&nav)) { const char *current_path = imv_navigator_selection(&nav); if(!current_path) { fprintf(stderr, "No input files left. Exiting.\n"); @@ -435,7 +431,6 @@ int main(int argc, char** argv) imv_viewport_set_title(&view, title); imv_loader_load_path(&ldr, current_path); - imv_reload_watch(&reload, current_path); view.playing = 1; } @@ -574,7 +569,6 @@ int main(int argc, char** argv) imv_destroy_texture(&tex); imv_navigator_destroy(&nav); imv_destroy_viewport(&view); - imv_destroy_reload(&reload); if(font) { TTF_CloseFont(font); diff --git a/src/navigator.c b/src/navigator.c index fcaa93a..bd049c5 100644 --- a/src/navigator.c +++ b/src/navigator.c @@ -27,6 +27,7 @@ void imv_navigator_init(struct imv_navigator *nav) { nav->buf_size = 512; nav->paths = malloc(sizeof(char*) * nav->buf_size); + nav->mtimes = malloc(sizeof(time_t) * nav->buf_size); nav->num_paths = 0; nav->cur_path = 0; nav->last_move_direction = 1; @@ -38,25 +39,33 @@ void imv_navigator_destroy(struct imv_navigator *nav) if(nav->buf_size > 0) { free(nav->paths); nav->paths = NULL; + free(nav->mtimes); + nav->mtimes = NULL; nav->buf_size = 0; } nav->num_paths = 0; } -static void add_item(struct imv_navigator *nav, const char *path) +static void add_item(struct imv_navigator *nav, const char *path, + time_t mtime) { if(nav->buf_size == nav->num_paths) { char **new_paths; + time_t *new_mtimes; nav->buf_size *= 2; new_paths = realloc(nav->paths, sizeof(char*) * nav->buf_size); - if (new_paths == NULL) { + new_mtimes = realloc(nav->mtimes, sizeof(time_t) * nav->buf_size); + if (new_paths == NULL || new_mtimes == NULL) { perror("add_item"); free(nav->paths); + free(nav->mtimes); exit(1); } nav->paths = new_paths; + nav->mtimes = new_mtimes; } nav->paths[nav->num_paths] = strdup(path); + nav->mtimes[nav->num_paths] = mtime; nav->num_paths += 1; if(nav->num_paths == 1) { nav->changed = 1; @@ -82,13 +91,13 @@ void imv_navigator_add(struct imv_navigator *nav, const char *path, if(recursive) { imv_navigator_add(nav, path_buf, recursive); } else { - add_item(nav, path_buf); + add_item(nav, path_buf, path_info.st_mtim.tv_sec); } } closedir(d); } } else { - add_item(nav, path); + add_item(nav, path, path_info.st_mtim.tv_sec); } } @@ -198,6 +207,13 @@ int imv_navigator_poll_changed(struct imv_navigator *nav) nav->changed = 0; return 1; } else { + struct stat file_info; + if (stat(nav->paths[nav->cur_path], &file_info) == -1) + return 0; + if (nav->mtimes[nav->cur_path] != file_info.st_mtim.tv_sec) { + nav->mtimes[nav->cur_path] = file_info.st_mtim.tv_sec; + return 1; + } return 0; } } diff --git a/src/navigator.h b/src/navigator.h index 5b1d4a1..b23e41a 100644 --- a/src/navigator.h +++ b/src/navigator.h @@ -1,6 +1,8 @@ #ifndef IMV_NAVIGATOR_H #define IMV_NAVIGATOR_H +#include + /* Copyright (c) 2015 Harry Jeffery This program is free software; you can redistribute it and/or @@ -23,6 +25,7 @@ struct imv_navigator { int buf_size; int cur_path; char **paths; + time_t *mtimes; int last_move_direction; int changed; }; @@ -57,7 +60,8 @@ void imv_navigator_select_str(struct imv_navigator *nav, const int path); /* Return the index of the path given. Returns -1 if not found. */ int imv_navigator_find_path(struct imv_navigator *nav, const char *path); -/* Returns 1 if the currently selected path has changed since last called */ +/* Returns 1 if either the currently selected path or underlying file has + * changed since last called */ int imv_navigator_poll_changed(struct imv_navigator *nav); #endif diff --git a/src/reload.c b/src/reload.c deleted file mode 100644 index a307d45..0000000 --- a/src/reload.c +++ /dev/null @@ -1,49 +0,0 @@ -#include -#include -#include -#include - -#include "reload.h" - -void imv_init_reload(struct imv_reload *rld) -{ - rld->fd = inotify_init1(IN_NONBLOCK); - if(rld->fd == -1) { - perror("imv_init_reload"); - } - - rld->wd = 0; -} - -void imv_reload_watch(struct imv_reload *rld, const char *path) -{ - if(rld->wd != 0) { - inotify_rm_watch(rld->fd, rld->wd); - } - - rld->wd = inotify_add_watch(rld->fd, path, IN_CLOSE_WRITE); - if(rld->wd == -1) { - perror("imv_reload_watch"); - } -} - -int imv_reload_changed(struct imv_reload *rld) -{ - struct inotify_event ev; - ssize_t len = read(rld->fd, &ev, sizeof(ev)); - - if(len < 0) { - if(errno != EAGAIN) { - perror("imv_reload_changed"); - } - } else if(ev.mask & IN_CLOSE_WRITE) { - return 1; - } - - return 0; -} - -void imv_destroy_reload(struct imv_reload *rld) -{ - close(rld->fd); -} diff --git a/src/reload.h b/src/reload.h deleted file mode 100644 index 411647f..0000000 --- a/src/reload.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef IMV_RELOAD_H -#define IMV_RELOAD_H - -/* Copyright (c) 2015 Jose Diez - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -*/ - -struct imv_reload { - int fd; // inotify file descriptor - int wd; // watch descriptor -}; - -void imv_init_reload(struct imv_reload *rld); -void imv_reload_watch(struct imv_reload *rld, const char *path); -int imv_reload_changed(struct imv_reload *rld); -void imv_destroy_reload(struct imv_reload *rld); - -#endif -- cgit v1.2.3