nnn

mirror of https://github.com/jarun/nnn
Log | Files | Refs | README | LICENSE

commit 49f5108cfa84dea01630d92c6ab88bcf4317eae3
parent afeefcb703161b392e7a0b327db4e13a0bff85ad
Author: Arun Prakash Jana <engineerarun@gmail.com>
Date:   Sat, 13 Dec 2025 11:24:42 +0530

Avoid using tmp file to buffer output for floating window

Diffstat:
Msrc/nnn.c | 96+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
1 file changed, 72 insertions(+), 24 deletions(-)

diff --git a/src/nnn.c b/src/nnn.c @@ -4846,58 +4846,106 @@ static bool get_output(char *command, char *arg1, char *arg2, int fdout, bool pa */ static bool buffer_command_output(char * const cmds[], char *arg1, char *arg2, size_t numcmds, char **content_out, size_t *content_len_out) { - int fd = create_tmp_file(); - if (fd == -1) + int pipefd[2]; + if (pipe(pipefd) == -1) return FALSE; - while (numcmds) - get_output(cmds[--numcmds], arg1, arg2, fd, FALSE); + /* Execute all commands sequentially, writing to pipe */ + size_t cmd_idx = numcmds; + while (cmd_idx) { + char *command = cmds[--cmd_idx]; + if (!command || !*command) + continue; - close(fd); + /* Tokenize the command into an array */ + char *argv[EXEC_ARGS_MAX] = {0}; + int index = 0; + char *cmd = parseargs(command, argv, &index); + if (!cmd) + continue; - /* Read the temp file content */ - FILE *fp = fopen(g_tmpfpath, "r"); - if (!fp) { - unlink(g_tmpfpath); - return FALSE; + if (arg1) { + argv[index] = arg1; + ++index; + } + + if (arg2) { + argv[index] = arg2; + ++index; + } + + pid_t pid = fork(); + if (pid == 0) { + /* In child */ + close(pipefd[0]); + dup2(pipefd[1], STDOUT_FILENO); + dup2(pipefd[1], STDERR_FILENO); + close(pipefd[1]); + + execvp(*argv, argv); + _exit(EXIT_SUCCESS); + } + + /* In parent */ + if (pid > 0) + waitpid(pid, NULL, 0); + free(cmd); } + /* Close write end so read end can detect EOF */ + close(pipefd[1]); + /* Allocate buffer for content */ char *content = NULL; size_t content_size = 0; size_t content_len = 0; - size_t line_len = 0; - char line[4096]; + char read_buf[8192]; - /* Read upto 16 MB content from file */ - while ((content_len < (size_t)SIZE_16MB) && fgets(line, sizeof(line), fp)) { - line_len = xstrlen(line); - if (content_len + line_len + 1 > content_size) { + /* Read directly from pipe into buffer */ + while (content_len < (size_t)SIZE_16MB) { + ssize_t nread = read(pipefd[0], read_buf, sizeof(read_buf)); + if (nread <= 0) + break; + + /* Grow buffer if needed */ + if (content_len + nread + 1 > content_size) { size_t new_size = content_size ? content_size * 2 : 8192; + /* Ensure new_size is large enough */ + while (new_size < content_len + nread + 1) + new_size *= 2; char *new_content = realloc(content, new_size); if (!new_content) { free(content); - fclose(fp); - unlink(g_tmpfpath); + close(pipefd[0]); return FALSE; } content = new_content; content_size = new_size; } - if (content) { - xstrsncpy(content + content_len, line, content_size - content_len); - content_len += line_len; - } + /* Append read data to buffer */ + memcpy(content + content_len, read_buf, nread); + content_len += nread; } - fclose(fp); - unlink(g_tmpfpath); + + close(pipefd[0]); if (!content || content_len == 0) { free(content); return FALSE; } + /* Null-terminate the buffer */ + if (content_len + 1 > content_size) { + char *new_content = realloc(content, content_len + 1); + if (!new_content) { + free(content); + return FALSE; + } + content = new_content; + } + content[content_len] = '\0'; + *content_out = content; *content_len_out = content_len; return TRUE;