Merge pull request #68 from czarkoff/reload
Use stat(2) to monitor file changes
This commit is contained in:
commit
433d8195a7
|
@ -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);
|
||||
|
|
|
@ -27,6 +27,16 @@ void imv_navigator_init(struct imv_navigator *nav)
|
|||
{
|
||||
nav->buf_size = 512;
|
||||
nav->paths = malloc(sizeof(char*) * nav->buf_size);
|
||||
if (nav->paths == NULL) {
|
||||
perror("imv_navigator_init");
|
||||
exit(1);
|
||||
}
|
||||
nav->mtimes = malloc(sizeof(time_t) * nav->buf_size);
|
||||
if (nav->paths == NULL) {
|
||||
perror("imv_navigator_init");
|
||||
free(nav->paths);
|
||||
exit(1);
|
||||
}
|
||||
nav->num_paths = 0;
|
||||
nav->cur_path = 0;
|
||||
nav->last_move_direction = 1;
|
||||
|
@ -38,22 +48,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) {
|
||||
int new_buf_size = nav->buf_size * 2;
|
||||
char **new_paths = malloc(sizeof(char*) * new_buf_size);
|
||||
memcpy(new_paths, nav->paths, sizeof(char*) * nav->buf_size);
|
||||
free(nav->paths);
|
||||
char **new_paths;
|
||||
time_t *new_mtimes;
|
||||
nav->buf_size *= 2;
|
||||
new_paths = realloc(nav->paths, sizeof(char*) * nav->buf_size);
|
||||
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->buf_size = new_buf_size;
|
||||
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;
|
||||
|
@ -79,13 +100,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -195,6 +216,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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef IMV_NAVIGATOR_H
|
||||
#define IMV_NAVIGATOR_H
|
||||
|
||||
#include <time.h>
|
||||
|
||||
/* 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
|
||||
|
|
49
src/reload.c
49
src/reload.c
|
@ -1,49 +0,0 @@
|
|||
#include <sys/inotify.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
|
||||
#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);
|
||||
}
|
31
src/reload.h
31
src/reload.h
|
@ -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
|
Loading…
Reference in a new issue