Read all available inotify events

Loop reading from inotify fd in arl_handle(); requires non-blocking inotify fd.
This commit is contained in:
Bert Münnich 2017-05-17 20:14:36 +02:00
parent 6695cd4c34
commit 0e1a85d224
1 changed files with 32 additions and 27 deletions

View File

@ -16,6 +16,7 @@
* along with sxiv. If not, see <http://www.gnu.org/licenses/>. * along with sxiv. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <errno.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
@ -62,37 +63,41 @@ bool arl_handle(arl_t *arl, const char *filepath)
char *ptr; char *ptr;
const struct inotify_event *event; const struct inotify_event *event;
ssize_t len = read(arl->fd, buf, sizeof(buf)); for (;;) {
ssize_t len = read(arl->fd, buf, sizeof(buf));
if (len == -1) if (len == -1) {
return false; if (errno == EINTR)
continue;
for (ptr = buf; ptr < buf + len; ptr += sizeof(*event) + event->len) { break;
event = (const struct inotify_event*) ptr;
/* events from watching the file itself */
if (event->mask & IN_CLOSE_WRITE) {
reload = true;
} }
if (event->mask & IN_DELETE_SELF) for (ptr = buf; ptr < buf + len; ptr += sizeof(*event) + event->len) {
arl_setup_dir(arl, filepath); event = (const struct inotify_event*) ptr;
/* events from watching the file's directory */ /* events from watching the file itself */
if (event->mask & IN_CREATE) { if (event->mask & IN_CLOSE_WRITE) {
char *fntmp = strdup(filepath);
char *fn = basename(fntmp);
if (STREQ(event->name, fn)) {
/* this is the file we're looking for */
/* cleanup, this has not been one-shot */
if (arl->watching_dir) {
inotify_rm_watch(arl->fd, arl->wd);
arl->watching_dir = false;
}
reload = true; reload = true;
} }
free(fntmp); if (event->mask & IN_DELETE_SELF)
arl_setup_dir(arl, filepath);
/* events from watching the file's directory */
if (event->mask & IN_CREATE) {
char *fntmp = strdup(filepath);
char *fn = basename(fntmp);
if (STREQ(event->name, fn)) {
/* this is the file we're looking for */
/* cleanup, this has not been one-shot */
if (arl->watching_dir) {
inotify_rm_watch(arl->fd, arl->wd);
arl->watching_dir = false;
}
reload = true;
}
free(fntmp);
}
} }
} }
return reload; return reload;
@ -101,7 +106,7 @@ bool arl_handle(arl_t *arl, const char *filepath)
void arl_init(arl_t *arl) void arl_init(arl_t *arl)
{ {
/* this needs to be done only once */ /* this needs to be done only once */
arl->fd = inotify_init(); arl->fd = inotify_init1(IN_CLOEXEC | IN_NONBLOCK);
arl->watching_dir = false; arl->watching_dir = false;
if (arl->fd == -1) if (arl->fd == -1)
error(0, 0, "Could not initialize inotify, no automatic image reloading"); error(0, 0, "Could not initialize inotify, no automatic image reloading");