summaryrefslogtreecommitdiffstats
path: root/main.c
diff options
context:
space:
mode:
authorBert Münnich <ber.t@posteo.de>2014-11-27 22:37:20 +0100
committerBert Münnich <ber.t@posteo.de>2014-11-27 22:37:20 +0100
commit216ad81b59a7b3a9a4d1f83a26fa2a23ff17a0e0 (patch)
treee7e735ee3073e40eaec1b05342a94409fb1c165e /main.c
parent51854c614873f59571e80da79f0dc0e8446cbf21 (diff)
downloadnsxiv-216ad81b59a7b3a9a4d1f83a26fa2a23ff17a0e0.tar.zst
Pass file paths to key handler via stdin; fixes issue #187
Diffstat (limited to 'main.c')
-rw-r--r--main.c85
1 files changed, 48 insertions, 37 deletions
diff --git a/main.c b/main.c
index f8dbab8..57798c4 100644
--- a/main.c
+++ b/main.c
@@ -481,12 +481,13 @@ void clear_resize(void)
void run_key_handler(const char *key, unsigned int mask)
{
pid_t pid;
- int i, j, retval, status;
- int fcnt = mode == MODE_THUMB && markcnt > 0 ? markcnt : 1;
+ FILE *pfs;
+ bool marked = mode == MODE_THUMB && markcnt > 0;
bool changed = false;
- char **args, kstr[32], oldbar[BAR_L_LEN];
- struct stat *oldst, newst;
- struct { int fn; struct stat st; } *finfo;
+ int f, i, pfd[2], retval, status;
+ int fcnt = marked ? markcnt : 1;
+ char kstr[32], oldbar[BAR_L_LEN];
+ struct stat *oldst, st;
if (keyhandler.cmd == NULL) {
if (!keyhandler.warned) {
@@ -498,55 +499,66 @@ void run_key_handler(const char *key, unsigned int mask)
if (key == NULL)
return;
- finfo = s_malloc(fcnt * sizeof(*finfo));
- args = s_malloc((fcnt + 3) * sizeof(*args));
- args[0] = keyhandler.cmd;
- args[1] = kstr;
- args[fcnt+2] = NULL;
- if (mode == MODE_IMAGE || markcnt == 0) {
- finfo[0].fn = fileidx;
- stat(files[fileidx].path, &finfo[0].st);
- args[2] = (char*) files[fileidx].path;
- } else for (i = j = 0; i < filecnt; i++) {
- if (files[i].marked) {
- finfo[j].fn = i;
- stat(files[i].path, &finfo[j++].st);
- args[j+1] = (char*) files[i].path;
- }
+ if (pipe(pfd) < 0) {
+ warn("could not create pipe for key handler");
+ return;
}
- snprintf(kstr, sizeof(kstr), "%s%s%s%s",
- mask & ControlMask ? "C-" : "",
- mask & Mod1Mask ? "M-" : "",
- mask & ShiftMask ? "S-" : "", key);
+ if ((pfs = fdopen(pfd[1], "w")) == NULL) {
+ close(pfd[0]), close(pfd[1]);
+ warn("could not open pipe for key handler");
+ return;
+ }
+ oldst = s_malloc(fcnt * sizeof(*oldst));
memcpy(oldbar, win.bar.l.buf, sizeof(oldbar));
strncpy(win.bar.l.buf, "Running key handler...", win.bar.l.size);
win_draw(&win);
win_set_cursor(&win, CURSOR_WATCH);
+ snprintf(kstr, sizeof(kstr), "%s%s%s%s",
+ mask & ControlMask ? "C-" : "",
+ mask & Mod1Mask ? "M-" : "",
+ mask & ShiftMask ? "S-" : "", key);
+
if ((pid = fork()) == 0) {
- execv(keyhandler.cmd, args);
+ close(pfd[1]);
+ dup2(pfd[0], 0);
+ execl(keyhandler.cmd, keyhandler.cmd, kstr, NULL);
warn("could not exec key handler");
exit(EXIT_FAILURE);
- } else if (pid < 0) {
+ }
+ close(pfd[0]);
+ if (pid < 0) {
+ fclose(pfs);
warn("could not fork key handler");
goto end;
}
+
+ for (f = i = 0; f < fcnt; i++) {
+ if ((marked && files[i].marked) || (!marked && i == fileidx)) {
+ stat(files[i].path, &oldst[f]);
+ fprintf(pfs, "%s\n", files[i].name);
+ f++;
+ }
+ }
+ fclose(pfs);
waitpid(pid, &status, 0);
retval = WEXITSTATUS(status);
if (WIFEXITED(status) == 0 || retval != 0)
warn("key handler exited with non-zero return value: %d", retval);
- for (i = 0; i < fcnt; i++) {
- oldst = &finfo[i].st;
- if (stat(files[finfo[i].fn].path, &newst) != 0 ||
- memcmp(&oldst->st_mtime, &newst.st_mtime, sizeof(newst.st_mtime)) != 0)
- {
- if (tns.thumbs != NULL) {
- tns_unload(&tns, finfo[i].fn);
- tns.loadnext = MIN(tns.loadnext, finfo[i].fn);
+ for (f = i = 0; f < fcnt; i++) {
+ if ((marked && files[i].marked) || (!marked && i == fileidx)) {
+ if (stat(files[i].path, &st) != 0 ||
+ memcmp(&oldst[f].st_mtime, &st.st_mtime, sizeof(st.st_mtime)) != 0)
+ {
+ if (tns.thumbs != NULL) {
+ tns_unload(&tns, i);
+ tns.loadnext = MIN(tns.loadnext, i);
+ }
+ changed = true;
}
- changed = true;
+ f++;
}
}
end:
@@ -558,10 +570,9 @@ end:
memcpy(win.bar.l.buf, oldbar, win.bar.l.size);
}
}
+ free(oldst);
reset_cursor();
redraw();
- free(finfo);
- free(args);
}
#define MODMASK(mask) ((mask) & (ShiftMask|ControlMask|Mod1Mask))