Fix reading from pipe when running plugin

This commit is contained in:
Arun Prakash Jana 2020-05-10 00:47:02 +05:30
parent 151bbf000d
commit 1f51417c63
No known key found for this signature in database
GPG key ID: A75979F35C080412

115
src/nnn.c
View file

@ -1710,17 +1710,18 @@ static int spawn(char *file, char *arg1, char *arg2, const char *dir, uchar flag
retstatus = join(pid, flag); retstatus = join(pid, flag);
DPRINTF_D(pid); DPRINTF_D(pid);
if (flag & F_NORMAL) {
if (flag & F_CONFIRM) { if (flag & F_CONFIRM) {
printf("%s", messages[MSG_CONTINUE]); printf("%s", messages[MSG_CONTINUE]);
#ifndef NORL #ifndef NORL
fflush(stdout); fflush(stdout);
#endif #endif
while (getchar() != '\n'); while (getchar() != '\n');
}
refresh();
} }
if (flag & F_NORMAL)
refresh();
free(cmd); free(cmd);
} }
@ -4175,26 +4176,10 @@ static void show_help(const char *path)
unlink(g_tmpfpath); unlink(g_tmpfpath);
} }
static bool run_cmd_as_plugin(const char *path, const char *file, char *runfile) static bool run_cmd_as_plugin(const char *path, const char *file, char *runfile, uchar flags)
{ {
uchar flags = F_CLI | F_CONFIRM;
size_t len; size_t len;
/* Get rid of preceding _ */
++file;
if (!*file)
return FALSE;
/* Check if GUI flags are to be used */
if (*file == '|') {
flags = F_NOTRACE | F_NOWAIT;
++file;
if (!*file)
return FALSE;
}
xstrsncpy(g_buf, file, PATH_MAX); xstrsncpy(g_buf, file, PATH_MAX);
len = xstrlen(g_buf); len = xstrlen(g_buf);
@ -4219,10 +4204,6 @@ static bool plctrl_init(void)
/* g_tmpfpath is used to generate tmp file names */ /* g_tmpfpath is used to generate tmp file names */
g_tmpfpath[tmpfplen - 1] = '\0'; g_tmpfpath[tmpfplen - 1] = '\0';
mkpath(g_tmpfpath, g_buf, g_pipepath); mkpath(g_tmpfpath, g_buf, g_pipepath);
unlink(g_pipepath);
if (mkfifo(g_pipepath, 0600) != 0)
return _FAILURE;
setenv(env_cfg[NNN_PIPE], g_pipepath, TRUE); setenv(env_cfg[NNN_PIPE], g_pipepath, TRUE);
return _SUCCESS; return _SUCCESS;
@ -4302,44 +4283,73 @@ static void readpipe(int fd, char **path, char **lastname, char **lastdir)
static bool run_selected_plugin(char **path, const char *file, char *runfile, char **lastname, char **lastdir) static bool run_selected_plugin(char **path, const char *file, char *runfile, char **lastname, char **lastdir)
{ {
bool cmd_as_plugin = FALSE;
uchar flags = 0;
if (!(g_states & STATE_PLUGIN_INIT)) { if (!(g_states & STATE_PLUGIN_INIT)) {
plctrl_init(); plctrl_init();
g_states |= STATE_PLUGIN_INIT; g_states |= STATE_PLUGIN_INIT;
} }
int fd = open(g_pipepath, O_RDONLY | O_NONBLOCK); if (*file == '_') {
flags = F_MULTI | F_CONFIRM;
if (fd == -1) /* Get rid of preceding _ */
return FALSE; ++file;
if (!*file)
return FALSE;
#ifdef __linux__ /* Check if GUI flags are to be used */
DPRINTF_D(fcntl(fd, F_GETPIPE_SZ)); if (*file == '|') {
/* Increase the pipe buffer size to 1 MB */ flags = F_NOTRACE | F_NOWAIT;
if (fcntl(fd, F_SETPIPE_SZ, 1024*1024) == -1) { ++file;
DPRINTF_S(strerror(errno));
if (!*file)
return FALSE;
run_cmd_as_plugin(*path, file, runfile, flags);
return TRUE;
}
cmd_as_plugin = TRUE;
} }
DPRINTF_D(fcntl(fd, F_GETPIPE_SZ));
#endif
/* Run plugin from command */ if (mkfifo(g_pipepath, 0600) != 0)
if (*file == '_') return _FAILURE;
run_cmd_as_plugin(*path, file, runfile);
/* Run command from plugin */ exitcurses();
else {
/* Generate absolute path to plugin */
mkpath(plugindir, file, g_buf);
if (runfile && runfile[0]) { if (fork() == 0) { // In child
xstrsncpy(*lastname, runfile, NAME_MAX); int wfd = open(g_pipepath, O_WRONLY | O_NONBLOCK);
spawn(g_buf, *lastname, *path, *path, F_NORMAL);
if (wfd == -1)
return FALSE;
if (!cmd_as_plugin) {
/* Generate absolute path to plugin */
mkpath(plugindir, file, g_buf);
if (runfile && runfile[0]) {
xstrsncpy(*lastname, runfile, NAME_MAX);
spawn(g_buf, *lastname, *path, *path, 0);
} else
spawn(g_buf, NULL, *path, *path, 0);
} else } else
spawn(g_buf, NULL, *path, *path, F_NORMAL); run_cmd_as_plugin(*path, file, runfile, flags);
close(wfd);
_exit(0);
} }
readpipe(fd, path, lastname, lastdir); int rfd = open(g_pipepath, O_RDONLY);
readpipe(rfd, path, lastname, lastdir);
close(rfd);
refresh();
unlink(g_pipepath);
close(fd);
return TRUE; return TRUE;
} }
@ -6822,9 +6832,6 @@ static void cleanup(void)
free(ihashbmp); free(ihashbmp);
free(bookmark); free(bookmark);
free(plug); free(plug);
unlink(g_pipepath);
#ifdef DBGMODE #ifdef DBGMODE
disabledbg(); disabledbg();
#endif #endif