Fix #532: support picker and list modes together

This commit is contained in:
Arun Prakash Jana 2020-04-24 23:35:43 +05:30
parent fffaa74a09
commit d118c4cc24
No known key found for this signature in database
GPG Key ID: A75979F35C080412
1 changed files with 59 additions and 40 deletions

View File

@ -1141,12 +1141,12 @@ static void appendfpath(const char *path, const size_t len)
} }
/* Write selected file paths to fd, linefeed separated */ /* Write selected file paths to fd, linefeed separated */
static size_t seltofile(int fd, uint *pcount) static size_t seltofile(int fd, uint *pcount, bool tgt)
{ {
uint lastpos, count = 0; uint lastpos, count = 0;
char *pbuf = pselbuf; char *pbuf = pselbuf;
size_t pos = 0, len; size_t pos = 0, len;
ssize_t r; ssize_t r, prefixlen, initlen, tgtlen;
if (pcount) if (pcount)
*pcount = 0; *pcount = 0;
@ -1156,13 +1156,33 @@ static size_t seltofile(int fd, uint *pcount)
lastpos = selbufpos - 1; lastpos = selbufpos - 1;
if (tgt) {
prefixlen = (ssize_t)xstrsncpy(g_buf, prefixpath, PATH_MAX) - 1;
initlen = strlen(initpath);
}
while (pos <= lastpos) { while (pos <= lastpos) {
len = xstrlen(pbuf); len = xstrlen(pbuf);
pos += len; pos += len;
r = write(fd, pbuf, len); if (!tgt) {
if (r != (ssize_t)len) r = write(fd, pbuf, len);
return pos; if (r != (ssize_t)len)
return pos;
} else {
if (!strncmp(initpath, pbuf, initlen)) {
tgtlen = xstrsncpy(g_buf + prefixlen, pbuf + initlen, PATH_MAX - prefixlen - 1);
tgtlen += prefixlen - 1;
} else
tgtlen = (ssize_t)xstrsncpy(g_buf, pbuf, PATH_MAX) - 1;
r = write(fd, g_buf, tgtlen);
if (r != tgtlen) {
DPRINTF_S(pbuf);
DPRINTF_S(g_buf);
return 0;
}
}
if (pos <= lastpos) { if (pos <= lastpos) {
if (write(fd, "\n", 1) != 1) if (write(fd, "\n", 1) != 1)
@ -1251,7 +1271,7 @@ static void endselection(void)
return; return;
} }
seltofile(fd, NULL); seltofile(fd, NULL, FALSE);
if (close(fd)) { if (close(fd)) {
DPRINTF_S(strerror(errno)); DPRINTF_S(strerror(errno));
printwarn(NULL); printwarn(NULL);
@ -1323,7 +1343,7 @@ static int editselection(void)
return -1; return -1;
} }
seltofile(fd, NULL); seltofile(fd, NULL, FALSE);
if (close(fd)) { if (close(fd)) {
DPRINTF_S(strerror(errno)); DPRINTF_S(strerror(errno));
return -1; return -1;
@ -1794,7 +1814,7 @@ static bool cpmv_rename(int choice, const char *path)
if (!count) if (!count)
goto finish; goto finish;
} else } else
seltofile(fd, &count); seltofile(fd, &count, FALSE);
close(fd); close(fd);
@ -1904,8 +1924,8 @@ static bool batch_rename(const char *path)
for (i = 0; i < ndents; ++i) for (i = 0; i < ndents; ++i)
appendfpath(dents[i].name, NAME_MAX); appendfpath(dents[i].name, NAME_MAX);
seltofile(fd1, &count); seltofile(fd1, &count, FALSE);
seltofile(fd2, NULL); seltofile(fd2, NULL, FALSE);
close(fd2); close(fd2);
if (dir) /* Don't retain dir entries in selection */ if (dir) /* Don't retain dir entries in selection */
@ -6742,9 +6762,13 @@ int main(int argc, char *argv[])
break; break;
cfg.picker = 1; cfg.picker = 1;
if (optarg[0] == '-' && optarg[1] == '\0') if (optarg[0] == '-' && optarg[1] == '\0') {
cfg.pickraw = 1; cfg.pickraw = 1;
else { if (!isatty(STDOUT_FILENO)) {
fprintf(stderr, "stdout !tty\n");
return _FAILURE;
}
} else {
int fd = open(optarg, O_WRONLY | O_CREAT, 0600); int fd = open(optarg, O_WRONLY | O_CREAT, 0600);
if (fd == -1) { if (fd == -1) {
@ -6810,27 +6834,17 @@ int main(int argc, char *argv[])
atexit(cleanup); atexit(cleanup);
if (!cfg.picker) { /* Check if we are in path list mode */
/* Confirm we are in a terminal */ if (!isatty(STDIN_FILENO)) {
if (!isatty(STDOUT_FILENO)) /* This is the same as listpath */
exit(1); initpath = load_input();
if (!initpath) {
/* Now we are in path list mode */ fprintf(stderr, "!initpath\n");
if (!isatty(STDIN_FILENO)) { return _FAILURE;
/* This is the same as listpath */
initpath = load_input();
if (!initpath)
exit(1);
/* We return to tty */
dup2(STDOUT_FILENO, STDIN_FILENO);
} }
}
/* Prevent picker and list mode conflict */ /* We return to tty */
if (!isatty(STDIN_FILENO) || !isatty(STDOUT_FILENO)) { dup2(STDOUT_FILENO, STDIN_FILENO);
fprintf(stderr, "stdin/out conflict\n");
return _FAILURE;
} }
home = getenv("HOME"); home = getenv("HOME");
@ -7015,9 +7029,6 @@ int main(int argc, char *argv[])
mousemask(mask, NULL); mousemask(mask, NULL);
#endif #endif
if (listpath)
spawn("rm -rf", initpath, NULL, NULL, F_SILENT);
exitcurses(); exitcurses();
#ifndef NORL #ifndef NORL
@ -7027,15 +7038,23 @@ int main(int argc, char *argv[])
} }
#endif #endif
if (cfg.pickraw) { if (cfg.pickraw || cfg.picker) {
if (selbufpos && (seltofile(1, NULL) != (size_t)(selbufpos))) if (selbufpos) {
xerror(); int fd = cfg.pickraw ? 1 : open(selpath, O_WRONLY | O_CREAT, 0600);
} else if (cfg.picker) {
if (selbufpos) if ((fd == -1) || (seltofile(fd, NULL, TRUE) != (size_t)(selbufpos)))
writesel(pselbuf, selbufpos - 1); xerror();
if (fd > 1)
close(fd);
}
} else if (selpath) } else if (selpath)
unlink(selpath); unlink(selpath);
/* Remove tmp dir in list mode */
if (listpath)
spawn("rm -rf", initpath, NULL, NULL, F_NOTRACE | F_MULTI);
/* Free the regex */ /* Free the regex */
#ifdef PCRE #ifdef PCRE
pcre_free(archive_pcre); pcre_free(archive_pcre);