From 1d60b6a4759c0d78c5046e21a12dff9a667d90ae Mon Sep 17 00:00:00 2001
From: Arun Prakash Jana <engineerarun@gmail.com>
Date: Sat, 8 Feb 2020 00:11:10 +0530
Subject: [PATCH] Fix empty dir on list files

---
 src/nnn.c | 61 +++++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 50 insertions(+), 11 deletions(-)

diff --git a/src/nnn.c b/src/nnn.c
index 20e082e3..8c7cfc32 100644
--- a/src/nnn.c
+++ b/src/nnn.c
@@ -973,7 +973,7 @@ static char *common_prefix(const char *s, char *prefix)
 		blocks = len >> _WSHIFT;
 		len &= LONG_SIZE - 1;
 
-		while (i < blocks && !(*x ^ *y))
+		while (i < blocks && (*x == *y))
 			++x, ++y, ++i;
 
 		/* This should always return */
@@ -6093,6 +6093,9 @@ static char *make_tmp_tree(char **paths, ssize_t entries, const char *prefix)
 	xstrlcpy(tmpdir, g_tmpfpath, g_tmpfplen);
 	xstrlcpy(tmp, "/nnnXXXXXX", 11);
 
+	/* Points right after the base tmp dir */
+	tmp += 10;
+
 	if (!mkdtemp(tmpdir)) {
 		free(tmpdir);
 
@@ -6109,14 +6112,19 @@ static char *make_tmp_tree(char **paths, ssize_t entries, const char *prefix)
 			continue;
 		}
 
-		xstrlcpy(tmp + 10, paths[i] + len, strlen(paths[i]) + 1);
+		/* Don't copy the common prefix */
+		xstrlcpy(tmp, paths[i] + len, strlen(paths[i]) - len + 1);
 
-		slash = xmemrchr((uchar *)tmp, '/', strlen(paths[i]) + 11);
-		*slash = '\0';
+		/* Get the dir containing the path */
+		slash = xmemrchr((uchar *)tmp, '/', strlen(paths[i]) - len);
+		if (slash)
+			*slash = '\0';
 
 		xmktree(tmpdir, TRUE);
 
-		*slash = '/';
+		if (slash)
+			*slash = '/';
+
 		if (symlink(paths[i], tmpdir)) {
 			DPRINTF_S(paths[i]);
 			DPRINTF_S(strerror(errno));
@@ -6126,7 +6134,8 @@ static char *make_tmp_tree(char **paths, ssize_t entries, const char *prefix)
 	if (ignore)
 		g_states |= STATE_MSG;
 
-	tmp[10] = '\0';
+	/* Get the dir in which to start */
+	*tmp = '\0';
 	return tmpdir;
 }
 
@@ -6139,6 +6148,7 @@ static char *load_input()
 	size_t offsets[LIST_FILES_MAX];
 	char **paths = NULL;
 	ssize_t input_read, total_read = 0, off = 0;
+	bool dotfirst = FALSE;
 
 	if (!input) {
 		DPRINTF_S(strerror(errno));
@@ -6151,12 +6161,15 @@ static char *load_input()
 	}
 
 	while (chunk_count < 512) {
-		input_read = read(STDIN_FILENO, input, chunk);
+		input_read = read(STDIN_FILENO, input + total_read, chunk);
 		if (input_read < 0) {
 			DPRINTF_S(strerror(errno));
 			goto malloc_1;
 		}
 
+		if (input_read == 0)
+			break;
+
 		total_read += input_read;
 		++chunk_count;
 
@@ -6177,12 +6190,18 @@ static char *load_input()
 			off = next - input;
 		}
 
-		if (input_read < chunk)
-			break;
-
 		if (chunk_count == 512)
 			goto malloc_1;
 
+		/* We don't need to allocate another chunk */
+		if (chunk_count == (total_read - input_read) / chunk)
+			continue;
+
+		chunk_count = total_read / chunk;
+		if (total_read % chunk)
+			++chunk_count;
+
+
 		if (!(input = xrealloc(input, (chunk_count + 1) * chunk)))
 			return NULL;
 	}
@@ -6194,6 +6213,10 @@ static char *load_input()
 		offsets[entries++] = off;
 	}
 
+	DPRINTF_D(entries);
+	DPRINTF_D(total_read);
+	DPRINTF_D(chunk_count);
+
 	if (!entries)
 		goto malloc_1;
 
@@ -6210,10 +6233,20 @@ static char *load_input()
 	if (!g_prefixpath)
 		goto malloc_1;
 
+	if (paths[0][0] == '.' && paths[0][1] == '\0')
+		dotfirst = TRUE;
+
 	if (!(paths[0] = xrealpath(paths[0], cwd)))
 		goto malloc_1; // free all entries
 
-	xstrlcpy(g_prefixpath, paths[0], strlen(paths[0]) + 1);
+	DPRINTF_S(paths[0]);
+
+	if (dotfirst)
+		xstrlcpy(g_prefixpath, paths[0], strlen(paths[0]) + 1);
+	else
+		xstrlcpy(g_prefixpath, dirname(paths[0]), strlen(dirname(paths[0])) + 1);
+
+	DPRINTF_S(g_prefixpath);
 
 	for (i = 1; i < entries; ++i) {
 		if (!(paths[i] = xrealpath(paths[i], cwd))) {
@@ -6222,12 +6255,18 @@ static char *load_input()
 
 		}
 
+		DPRINTF_S(paths[i]);
+
 		if (!common_prefix(paths[i], g_prefixpath)) {
 			entries = i + 1; // free from the current entry
 			goto malloc_2;
 		}
+
+		DPRINTF_S(g_prefixpath);
 	}
 
+	DPRINTF_S(g_prefixpath);
+
 	if (entries == 1) {
 		tmp = xmemrchr((uchar *)g_prefixpath, '/', strlen(g_prefixpath));
 		if (!tmp)
-- 
2.51.0