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:
| M | src/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;