st-externalpipe-0.8.4.diff 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. diff --git a/st.c b/st.c
  2. index 76b7e0d..0e9a614 100644
  3. --- a/st.c
  4. +++ b/st.c
  5. @@ -723,8 +723,14 @@ sigchld(int a)
  6. if ((p = waitpid(pid, &stat, WNOHANG)) < 0)
  7. die("waiting for pid %hd failed: %s\n", pid, strerror(errno));
  8. - if (pid != p)
  9. + if (pid != p) {
  10. + if (p == 0 && wait(&stat) < 0)
  11. + die("wait: %s\n", strerror(errno));
  12. +
  13. + /* reinstall sigchld handler */
  14. + signal(SIGCHLD, sigchld);
  15. return;
  16. + }
  17. if (WIFEXITED(stat) && WEXITSTATUS(stat))
  18. die("child exited with status %d\n", WEXITSTATUS(stat));
  19. @@ -1926,6 +1932,59 @@ strparse(void)
  20. }
  21. }
  22. +void
  23. +externalpipe(const Arg *arg)
  24. +{
  25. + int to[2];
  26. + char buf[UTF_SIZ];
  27. + void (*oldsigpipe)(int);
  28. + Glyph *bp, *end;
  29. + int lastpos, n, newline;
  30. +
  31. + if (pipe(to) == -1)
  32. + return;
  33. +
  34. + switch (fork()) {
  35. + case -1:
  36. + close(to[0]);
  37. + close(to[1]);
  38. + return;
  39. + case 0:
  40. + dup2(to[0], STDIN_FILENO);
  41. + close(to[0]);
  42. + close(to[1]);
  43. + execvp(((char **)arg->v)[0], (char **)arg->v);
  44. + fprintf(stderr, "st: execvp %s\n", ((char **)arg->v)[0]);
  45. + perror("failed");
  46. + exit(0);
  47. + }
  48. +
  49. + close(to[0]);
  50. + /* ignore sigpipe for now, in case child exists early */
  51. + oldsigpipe = signal(SIGPIPE, SIG_IGN);
  52. + newline = 0;
  53. + for (n = 0; n < term.row; n++) {
  54. + bp = term.line[n];
  55. + lastpos = MIN(tlinelen(n) + 1, term.col) - 1;
  56. + if (lastpos < 0)
  57. + break;
  58. + end = &bp[lastpos + 1];
  59. + for (; bp < end; ++bp)
  60. + if (xwrite(to[1], buf, utf8encode(bp->u, buf)) < 0)
  61. + break;
  62. + if ((newline = term.line[n][lastpos].mode & ATTR_WRAP))
  63. + continue;
  64. + if (xwrite(to[1], "\n", 1) < 0)
  65. + break;
  66. + newline = 0;
  67. + }
  68. + if (newline)
  69. + (void)xwrite(to[1], "\n", 1);
  70. + close(to[1]);
  71. + /* restore */
  72. + signal(SIGPIPE, oldsigpipe);
  73. +}
  74. +
  75. void
  76. strdump(void)
  77. {
  78. diff --git a/st.h b/st.h
  79. index 3d351b6..392b64e 100644
  80. --- a/st.h
  81. +++ b/st.h
  82. @@ -81,6 +81,7 @@ void die(const char *, ...);
  83. void redraw(void);
  84. void draw(void);
  85. +void externalpipe(const Arg *);
  86. void printscreen(const Arg *);
  87. void printsel(const Arg *);
  88. void sendbreak(const Arg *);