aboutsummaryrefslogtreecommitdiffstats
path: root/src/nnn.c
diff options
context:
space:
mode:
authorGravatar Arun Prakash Jana <engineerarun@gmail.com>2019-03-19 19:39:43 +0530
committerGravatar Arun Prakash Jana <engineerarun@gmail.com>2019-03-19 19:39:43 +0530
commit24b72f65c58e4a09d9b43230d8ad661536a59eb6 (patch)
tree7464b8453dda41ba120b17cfd9a35839430fae05 /src/nnn.c
parent40b98e8c9e78f8e1622968014ed903aeac8a790e (diff)
downloadnnn-24b72f65c58e4a09d9b43230d8ad661536a59eb6.tar.gz
Fix selection symbol (+) lost after a few seconds
This is fix on Linux. Someone has to test it on BSD and fix IF there's similar issue with the kevent based mechanism. We need to mask and check if the intended events are received because some events like IN_UNMOUNT, IN_Q_OVERFLOW or IN_IGNORED may arrive without knowledge.
Diffstat (limited to 'src/nnn.c')
-rw-r--r--src/nnn.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/src/nnn.c b/src/nnn.c
index 8c40042..b374306 100644
--- a/src/nnn.c
+++ b/src/nnn.c
@@ -402,8 +402,9 @@ static const char * const envs[] = {
/* Event handling */
#ifdef LINUX_INOTIFY
+#define NUM_EVENT_SLOTS 16 /* Make room for 16 events */
#define EVENT_SIZE (sizeof(struct inotify_event))
-#define EVENT_BUF_LEN (1024 * (EVENT_SIZE + 16))
+#define EVENT_BUF_LEN (EVENT_SIZE * NUM_EVENT_SLOTS)
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;
@@ -1415,7 +1416,9 @@ static int nextsel(int presel)
uint i;
const uint len = LEN(bindings);
#ifdef LINUX_INOTIFY
- static char inotify_buf[EVENT_BUF_LEN];
+ struct inotify_event *event;
+ static char inotify_buf[EVENT_BUF_LEN]
+ __attribute__ ((aligned(__alignof__(struct inotify_event))));
#elif defined(BSD_KQUEUE)
static struct kevent event_data[NUM_EVENT_SLOTS];
#endif
@@ -1442,14 +1445,27 @@ static int nextsel(int presel)
* Check for changes every odd second.
*/
#ifdef LINUX_INOTIFY
- if (!cfg.blkorder && inotify_wd >= 0 && idle & 1
- && read(inotify_fd, inotify_buf, EVENT_BUF_LEN) > 0)
+ if (!cfg.blkorder && inotify_wd >= 0 && (idle & 1)) {
+ ssize_t bytes = read(inotify_fd, inotify_buf, EVENT_BUF_LEN);
+ if (bytes > 0) {
+ for (char *ptr = inotify_buf; ptr < inotify_buf + bytes;
+ ptr += sizeof(struct inotify_event) + event->len) {
+ event = (struct inotify_event *) ptr;
+ DPRINTF_D(event->wd);
+ DPRINTF_D(event->mask);
+ if (event->mask & INOTIFY_MASK) {
+ c = CONTROL('L');
+ break;
+ }
+ }
+ }
+ }
#elif defined(BSD_KQUEUE)
if (!cfg.blkorder && event_fd >= 0 && idle & 1
&& kevent(kq, events_to_monitor, NUM_EVENT_SLOTS,
event_data, NUM_EVENT_FDS, &gtimeout) > 0)
-#endif
c = CONTROL('L');
+#endif
} else
idle = 0;