| @@ -240,29 +240,22 @@ void close_info(void) |
| 240 | 240 | | |
| 241 | 241 | | void open_info(void) |
| 242 | 242 | | { |
| 243 | | − | int pfd[2]; |
| 243 | + | spawn_t pfd; |
| 244 | 244 | | char w[12], h[12]; |
| 245 | + | char *argv[5]; |
| 245 | 246 | | |
| 246 | 247 | | if (info.f.err || info.fd >= 0 || win.bar.h == 0) |
| 247 | 248 | | return; |
| 248 | 249 | | win.bar.l.buf[0] = '\0'; |
| 249 | | − | if (pipe(pfd) < 0) |
| 250 | | − | return; |
| 251 | | − | if ((info.pid = fork()) == 0) { |
| 252 | | − | close(pfd[0]); |
| 253 | | − | dup2(pfd[1], 1); |
| 254 | | − | snprintf(w, sizeof(w), "%d", img.w); |
| 255 | | − | snprintf(h, sizeof(h), "%d", img.h); |
| 256 | | − | execl(info.f.cmd, info.f.cmd, files[fileidx].name, w, h, NULL); |
| 257 | | − | error(EXIT_FAILURE, errno, "exec: %s", info.f.cmd); |
| 258 | | − | } |
| 259 | | − | close(pfd[1]); |
| 260 | | − | if (info.pid < 0) { |
| 261 | | − | close(pfd[0]); |
| 262 | | − | } else { |
| 263 | | − | fcntl(pfd[0], F_SETFL, O_NONBLOCK); |
| 264 | | − | info.fd = pfd[0]; |
| 250 | + | snprintf(w, sizeof(w), "%d", img.w); |
| 251 | + | snprintf(h, sizeof(h), "%d", img.h); |
| 252 | + | construct_argv(argv, ARRLEN(argv), info.f.cmd, files[fileidx].name, w, h, NULL); |
| 253 | + | pfd = spawn(info.f.cmd, argv, X_READ); |
| 254 | + | if (pfd.readfd >= 0) { |
| 255 | + | fcntl(pfd.readfd, F_SETFL, O_NONBLOCK); |
| 256 | + | info.fd = pfd.readfd; |
| 265 | 257 | | info.i = info.lastsep = 0; |
| 258 | + | info.pid = pfd.pid; |
| 266 | 259 | | } |
| 267 | 260 | | } |
| 268 | 261 | | |
| @@ -510,15 +503,16 @@ void handle_key_handler(bool init) |
| 510 | 503 | | |
| 511 | 504 | | static bool run_key_handler(const char *key, unsigned int mask) |
| 512 | 505 | | { |
| 513 | | − | pid_t pid; |
| 514 | 506 | | FILE *pfs; |
| 515 | 507 | | bool marked = mode == MODE_THUMB && markcnt > 0; |
| 516 | 508 | | bool changed = false; |
| 517 | | − | int f, i, pfd[2]; |
| 509 | + | int f, i; |
| 518 | 510 | | int fcnt = marked ? markcnt : 1; |
| 519 | 511 | | char kstr[32]; |
| 520 | 512 | | struct stat *oldst, st; |
| 521 | 513 | | XEvent dump; |
| 514 | + | char *argv[3]; |
| 515 | + | spawn_t pfd; |
| 522 | 516 | | |
| 523 | 517 | | if (keyhandler.f.err) { |
| 524 | 518 | | if (!keyhandler.warned) { |
| @@ -530,41 +524,27 @@ static bool run_key_handler(const char *key, unsigned int mask) |
| 530 | 524 | | if (key == NULL) |
| 531 | 525 | | return false; |
| 532 | 526 | | |
| 533 | | − | if (pipe(pfd) < 0) { |
| 534 | | − | error(0, errno, "pipe"); |
| 535 | | − | return false; |
| 536 | | − | } |
| 537 | | − | if ((pfs = fdopen(pfd[1], "w")) == NULL) { |
| 538 | | − | error(0, errno, "open pipe"); |
| 539 | | − | close(pfd[0]), close(pfd[1]); |
| 540 | | − | return false; |
| 541 | | − | } |
| 542 | | − | oldst = emalloc(fcnt * sizeof(*oldst)); |
| 543 | | − | |
| 544 | 527 | | close_info(); |
| 545 | 528 | | strncpy(win.bar.l.buf, "Running key handler...", win.bar.l.size); |
| 546 | 529 | | win_draw(&win); |
| 547 | 530 | | win_set_cursor(&win, CURSOR_WATCH); |
| 531 | + | setenv("NSXIV_USING_NULL", options->using_null ? "1" : "0", 1); |
| 548 | 532 | | |
| 549 | 533 | | snprintf(kstr, sizeof(kstr), "%s%s%s%s", |
| 550 | 534 | | mask & ControlMask ? "C-" : "", |
| 551 | 535 | | mask & Mod1Mask ? "M-" : "", |
| 552 | 536 | | mask & ShiftMask ? "S-" : "", key); |
| 553 | | − | setenv("NSXIV_USING_NULL", options->using_null ? "1" : "0", 1); |
| 554 | | − | |
| 555 | | − | if ((pid = fork()) == 0) { |
| 556 | | − | close(pfd[1]); |
| 557 | | − | dup2(pfd[0], 0); |
| 558 | | − | execl(keyhandler.f.cmd, keyhandler.f.cmd, kstr, NULL); |
| 559 | | − | error(EXIT_FAILURE, errno, "exec: %s", keyhandler.f.cmd); |
| 560 | | − | } |
| 561 | | − | close(pfd[0]); |
| 562 | | − | if (pid < 0) { |
| 563 | | − | error(0, errno, "fork"); |
| 564 | | − | fclose(pfs); |
| 565 | | − | goto end; |
| 537 | + | construct_argv(argv, ARRLEN(argv), keyhandler.f.cmd, kstr, NULL); |
| 538 | + | pfd = spawn(keyhandler.f.cmd, argv, X_WRITE); |
| 539 | + | if (pfd.writefd < 0) |
| 540 | + | return false; |
| 541 | + | if ((pfs = fdopen(pfd.writefd, "w")) == NULL) { |
| 542 | + | close(pfd.writefd); |
| 543 | + | error(0, errno, "open pipe"); |
| 544 | + | return false; |
| 566 | 545 | | } |
| 567 | 546 | | |
| 547 | + | oldst = emalloc(fcnt * sizeof(*oldst)); |
| 568 | 548 | | for (f = i = 0; f < fcnt; i++) { |
| 569 | 549 | | if ((marked && (files[i].flags & FF_MARK)) || (!marked && i == fileidx)) { |
| 570 | 550 | | stat(files[i].path, &oldst[f]); |
| @@ -573,7 +553,7 @@ static bool run_key_handler(const char *key, unsigned int mask) |
| 573 | 553 | | } |
| 574 | 554 | | } |
| 575 | 555 | | fclose(pfs); |
| 576 | | − | while (waitpid(pid, NULL, 0) == -1 && errno == EINTR); |
| 556 | + | while (waitpid(pfd.pid, NULL, 0) == -1 && errno == EINTR); |
| 577 | 557 | | |
| 578 | 558 | | for (f = i = 0; f < fcnt; i++) { |
| 579 | 559 | | if ((marked && (files[i].flags & FF_MARK)) || (!marked && i == fileidx)) { |
| @@ -592,7 +572,6 @@ static bool run_key_handler(const char *key, unsigned int mask) |
| 592 | 572 | | /* drop user input events that occurred while running the key handler */ |
| 593 | 573 | | while (XCheckIfEvent(win.env.dpy, &dump, is_input_ev, NULL)); |
| 594 | 574 | | |
| 595 | | − | end: |
| 596 | 575 | | if (mode == MODE_IMAGE) { |
| 597 | 576 | | if (changed) { |
| 598 | 577 | | img_close(&img, true); |