Browse Source

Watch out for directory changes

master
Arun Prakash Jana 7 years ago
parent
commit
e4596db30a
No known key found for this signature in database GPG Key ID: A75979F35C080412
1 changed files with 58 additions and 6 deletions
  1. +58
    -6
      nnn.c

+ 58
- 6
nnn.c View File

@@ -1,5 +1,11 @@
/* See LICENSE file for copyright and license details. */ /* See LICENSE file for copyright and license details. */
#ifdef __linux__
#include <sys/inotify.h>
#define LINUX_INOTIFY
#endif
#include <sys/resource.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/statvfs.h>
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \ #if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) \
|| defined(__APPLE__) || defined(__APPLE__)
# include <sys/types.h> # include <sys/types.h>
@@ -7,8 +13,6 @@
# include <sys/sysmacros.h> # include <sys/sysmacros.h>
#endif #endif
#include <sys/wait.h> #include <sys/wait.h>
#include <sys/statvfs.h>
#include <sys/resource.h>


#include <ctype.h> #include <ctype.h>
#include <curses.h> #include <curses.h>
@@ -124,6 +128,11 @@ disabledbg()
#define printwarn() printmsg(strerror(errno)) #define printwarn() printmsg(strerror(errno))
#define istopdir(path) (path[1] == '\0' && path[0] == '/') #define istopdir(path) (path[1] == '\0' && path[0] == '/')


#ifdef LINUX_INOTIFY
#define EVENT_SIZE (sizeof(struct inotify_event))
#define EVENT_BUF_LEN (1024 * (EVENT_SIZE + 16))
#endif

typedef unsigned long ulong; typedef unsigned long ulong;
typedef unsigned int uint; typedef unsigned int uint;
typedef unsigned char uchar; typedef unsigned char uchar;
@@ -186,6 +195,11 @@ static const double div_2_pow_10 = 1.0 / 1024.0;
static uint _WSHIFT = (sizeof(ulong) == 8) ? 3 : 2; static uint _WSHIFT = (sizeof(ulong) == 8) ? 3 : 2;
static uchar color = 4; static uchar color = 4;


#ifdef LINUX_INOTIFY
static int inotify_fd, inotify_wd = -1;
static uint INOTIFY_MASK = IN_ATTRIB | IN_CREATE | IN_DELETE | IN_DELETE_SELF | IN_MODIFY | IN_MOVE_SELF | IN_MOVED_FROM | IN_MOVED_TO;
#endif

/* Utilities to open files, run actions */ /* Utilities to open files, run actions */
static char * const utils[] = { static char * const utils[] = {
#ifdef __APPLE__ #ifdef __APPLE__
@@ -741,7 +755,8 @@ printprompt(char *str)
printw(str); printw(str);
} }


/* Returns SEL_* if key is bound and 0 otherwise.
/*
* Returns SEL_* if key is bound and 0 otherwise.
* Also modifies the run and env pointers (used on SEL_{RUN,RUNARG}). * Also modifies the run and env pointers (used on SEL_{RUN,RUNARG}).
* The next keyboard input can be simulated by presel. * The next keyboard input can be simulated by presel.
*/ */
@@ -751,6 +766,9 @@ nextsel(char **run, char **env, int *presel)
static int c; static int c;
static uchar i; static uchar i;
static uint len = LEN(bindings); static uint len = LEN(bindings);
#ifdef LINUX_INOTIFY
static char inotify_buf[EVENT_BUF_LEN];
#endif


c = *presel; c = *presel;


@@ -759,9 +777,18 @@ nextsel(char **run, char **env, int *presel)
else else
*presel = 0; *presel = 0;


if (c == -1)
if (c == -1) {
++idle; ++idle;
else
#ifdef LINUX_INOTIFY
/* Do not check for directory changes in du
* mode. A redraw forces du calculation.
* Check for changes every odd second.
*/
if (!cfg.blkorder && inotify_wd >= 0 && idle & 1)
if (read(inotify_fd, inotify_buf, EVENT_BUF_LEN) > 0)
c = CONTROL('L');
#endif
} else
idle = 0; idle = 0;


for (i = 0; i < len; ++i) for (i = 0; i < len; ++i)
@@ -1811,7 +1838,7 @@ redraw(char *path)


/* No text wrapping in cwd line */ /* No text wrapping in cwd line */
if (!realpath(path, g_buf)) { if (!realpath(path, g_buf)) {
printmsg("Cannot resolve path");
printwarn();
return; return;
} }


@@ -1915,11 +1942,20 @@ browse(char *ipath, char *ifilter)
presel = 0; presel = 0;


begin: begin:
#ifdef LINUX_INOTIFY
if (inotify_wd >= 0)
inotify_rm_watch(inotify_fd, inotify_wd);
#endif

if (populate(path, oldpath, fltr) == -1) { if (populate(path, oldpath, fltr) == -1) {
printwarn(); printwarn();
goto nochange; goto nochange;
} }


#ifdef LINUX_INOTIFY
inotify_wd = inotify_add_watch(inotify_fd, path, INOTIFY_MASK);
#endif

for (;;) { for (;;) {
redraw(path); redraw(path);
nochange: nochange:
@@ -2584,6 +2620,15 @@ main(int argc, char *argv[])
cfg.showhidden = 1; cfg.showhidden = 1;
initfilter(cfg.showhidden, &ifilter); initfilter(cfg.showhidden, &ifilter);


#ifdef LINUX_INOTIFY
/* Initialize inotify */
inotify_fd = inotify_init1(IN_NONBLOCK);
if (inotify_fd < 0) {
fprintf(stderr, "Cannot initialize inotify: %s\n", strerror(errno));
exit(1);
}
#endif

/* Parse bookmarks string, if available */ /* Parse bookmarks string, if available */
bmstr = getenv("NNN_BMS"); bmstr = getenv("NNN_BMS");
if (bmstr) if (bmstr)
@@ -2628,6 +2673,13 @@ main(int argc, char *argv[])
initcurses(); initcurses();
browse(ipath, ifilter); browse(ipath, ifilter);
exitcurses(); exitcurses();

#ifdef LINUX_INOTIFY
/* Shutdown inotify */
if (inotify_wd >= 0)
inotify_rm_watch(inotify_fd, inotify_wd);
close(inotify_fd);
#endif
#ifdef DEBUGMODE #ifdef DEBUGMODE
disabledbg(); disabledbg();
#endif #endif


Loading…
Cancel
Save