autoreload: simplify and cleanup (#342)
the current code is quite hacky and complex as it mixes multiple pointers. all of this complexity is unnecessary. drop it by introducing an explicit scratch buffer instead of implicitly abusing `arl->filename` as one. this also reduces some unnecessary allocation overhead. additionally, the argument to arl_setup must be the result of `realpath(3)` (as commented in `nsxiv.h`). instead of commenting it, assert it. and lastly, rename `arl_setup` to `arl_add` since it's not doing any "setup" but rather *adding* a file to watch. Reviewed-on: https://codeberg.org/nsxiv/nsxiv/pulls/342 Reviewed-by: explosion-mental <explosion-mental@noreply.codeberg.org>
This commit is contained in:
parent
6d8ec5aee3
commit
94d531fd82
41
autoreload.c
41
autoreload.c
|
@ -1,4 +1,5 @@
|
||||||
/* Copyright 2017 Max Voit, Bert Muennich
|
/* Copyright 2017 Max Voit, Bert Muennich
|
||||||
|
* Copyright 2022 nsxiv contributors
|
||||||
*
|
*
|
||||||
* This file is a part of nsxiv.
|
* This file is a part of nsxiv.
|
||||||
*
|
*
|
||||||
|
@ -20,16 +21,14 @@
|
||||||
|
|
||||||
#if HAVE_INOTIFY
|
#if HAVE_INOTIFY
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/inotify.h>
|
#include <sys/inotify.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
static union {
|
static struct { char *buf; size_t len; } scratch;
|
||||||
char d[4096]; /* aligned buffer */
|
|
||||||
struct inotify_event e;
|
|
||||||
} buf;
|
|
||||||
|
|
||||||
void arl_init(arl_t *arl)
|
void arl_init(arl_t *arl)
|
||||||
{
|
{
|
||||||
|
@ -43,7 +42,7 @@ CLEANUP void arl_cleanup(arl_t *arl)
|
||||||
{
|
{
|
||||||
if (arl->fd != -1)
|
if (arl->fd != -1)
|
||||||
close(arl->fd);
|
close(arl->fd);
|
||||||
free(arl->filename);
|
free(scratch.buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rm_watch(int fd, int *wd)
|
static void rm_watch(int fd, int *wd)
|
||||||
|
@ -61,26 +60,32 @@ static void add_watch(int fd, int *wd, const char *path, uint32_t mask)
|
||||||
error(0, errno, "inotify: %s", path);
|
error(0, errno, "inotify: %s", path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void arl_setup(arl_t *arl, const char *filepath)
|
static char *arl_scratch_push(const char *filepath, size_t len)
|
||||||
{
|
{
|
||||||
char *base = strrchr(filepath, '/');
|
if (scratch.len < len + 1) {
|
||||||
|
scratch.len = len + 1;
|
||||||
|
scratch.buf = erealloc(scratch.buf, scratch.len);
|
||||||
|
}
|
||||||
|
scratch.buf[len] = '\0';
|
||||||
|
return memcpy(scratch.buf, filepath, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void arl_add(arl_t *arl, const char *filepath)
|
||||||
|
{
|
||||||
|
char *base, *dir;
|
||||||
|
|
||||||
if (arl->fd == -1)
|
if (arl->fd == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
rm_watch(arl->fd, &arl->wd_dir);
|
rm_watch(arl->fd, &arl->wd_dir);
|
||||||
rm_watch(arl->fd, &arl->wd_file);
|
rm_watch(arl->fd, &arl->wd_file);
|
||||||
|
|
||||||
add_watch(arl->fd, &arl->wd_file, filepath, IN_CLOSE_WRITE | IN_DELETE_SELF);
|
add_watch(arl->fd, &arl->wd_file, filepath, IN_CLOSE_WRITE | IN_DELETE_SELF);
|
||||||
|
|
||||||
free(arl->filename);
|
base = strrchr(filepath, '/');
|
||||||
arl->filename = estrdup(filepath);
|
assert(base != NULL); /* filepath must be result of `realpath(3)` */
|
||||||
|
dir = arl_scratch_push(filepath, base - filepath);
|
||||||
if (base != NULL) {
|
add_watch(arl->fd, &arl->wd_dir, dir, IN_CREATE | IN_MOVED_TO);
|
||||||
arl->filename[++base - filepath] = '\0';
|
arl->filename = arl_scratch_push(base + 1, strlen(base + 1));
|
||||||
add_watch(arl->fd, &arl->wd_dir, arl->filename, IN_CREATE | IN_MOVED_TO);
|
|
||||||
strcpy(arl->filename, base); /* NOLINT: basename will always be shorter than fullpath */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool arl_handle(arl_t *arl)
|
bool arl_handle(arl_t *arl)
|
||||||
|
@ -88,6 +93,8 @@ bool arl_handle(arl_t *arl)
|
||||||
bool reload = false;
|
bool reload = false;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
const struct inotify_event *e;
|
const struct inotify_event *e;
|
||||||
|
/* inotify_event aligned buffer */
|
||||||
|
static union { char d[4096]; struct inotify_event e; } buf;
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
ssize_t len = read(arl->fd, buf.d, sizeof(buf.d));
|
ssize_t len = read(arl->fd, buf.d, sizeof(buf.d));
|
||||||
|
@ -124,7 +131,7 @@ void arl_cleanup(arl_t *arl)
|
||||||
(void) arl;
|
(void) arl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void arl_setup(arl_t *arl, const char *filepath)
|
void arl_add(arl_t *arl, const char *filepath)
|
||||||
{
|
{
|
||||||
(void) arl;
|
(void) arl;
|
||||||
(void) filepath;
|
(void) filepath;
|
||||||
|
|
2
main.c
2
main.c
|
@ -350,7 +350,7 @@ void load_image(int new)
|
||||||
|
|
||||||
close_info();
|
close_info();
|
||||||
open_info();
|
open_info();
|
||||||
arl_setup(&arl, files[fileidx].path);
|
arl_add(&arl, files[fileidx].path);
|
||||||
title_dirty = true;
|
title_dirty = true;
|
||||||
|
|
||||||
if (img.multi.cnt > 0 && img.multi.animate)
|
if (img.multi.cnt > 0 && img.multi.animate)
|
||||||
|
|
4
nsxiv.h
4
nsxiv.h
|
@ -124,12 +124,12 @@ struct arl {
|
||||||
int fd;
|
int fd;
|
||||||
int wd_dir;
|
int wd_dir;
|
||||||
int wd_file;
|
int wd_file;
|
||||||
char *filename;
|
const char *filename;
|
||||||
};
|
};
|
||||||
|
|
||||||
void arl_init(arl_t*);
|
void arl_init(arl_t*);
|
||||||
void arl_cleanup(arl_t*);
|
void arl_cleanup(arl_t*);
|
||||||
void arl_setup(arl_t*, const char* /* result of realpath(3) */);
|
void arl_add(arl_t*, const char* /* result of realpath(3) */);
|
||||||
bool arl_handle(arl_t*);
|
bool arl_handle(arl_t*);
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue