commit b2f300c028bc4f805cc44c7107664ec555a65dc5
parent 9792967307fc14fa70b77ef5cc250463a1e1e08a
Author: Lucas Gabriel Vuotto <lvuotto92@gmail.com>
Date: Thu, 8 Jun 2017 12:07:29 -0300
[st][externalpipe] patch improvements
* Change how command are invoked: instead of running through /bin/sh, give the
parameters list to execvp
* Expose xwindow id so it can be used for command lines
* Fix a possible UB when tlinelen returns 0 which implies end = &bp[-1]
(happens when st has blank lines)
* Treat wrapped lines as a logical single line
* Respect st's coding style
Signed-off-by: Lucas Gabriel Vuotto <lvuotto92@gmail.com>
Diffstat:
3 files changed, 103 insertions(+), 76 deletions(-)
diff --git a/st.suckless.org/patches/externalpipe.md b/st.suckless.org/patches/externalpipe.md
@@ -27,7 +27,7 @@ Download
* [st-externalpipe-0.4.1.diff](st-externalpipe-0.4.1.diff)
* [st-externalpipe-0.5.diff](st-externalpipe-0.5.diff)
* [st-externalpipe-0.6.diff](st-externalpipe-0.6.diff)
-* [st-externalpipe-20170603-b331da5.diff](st-externalpipe-20170603-b331da5.diff)
+* [st-externalpipe-20170608-b331da5.diff](st-externalpipe-20170608-b331da5.diff)
Authors
-------
diff --git a/st.suckless.org/patches/st-externalpipe-20170603-b331da5.diff b/st.suckless.org/patches/st-externalpipe-20170603-b331da5.diff
@@ -1,75 +0,0 @@
-diff --git a/st.c b/st.c
-index 8d4a9f2..2cb0d45 100644
---- a/st.c
-+++ b/st.c
-@@ -138,6 +138,7 @@ static void printscreen(const Arg *) ;
- static void iso14755(const Arg *);
- static void toggleprinter(const Arg *);
- static void sendbreak(const Arg *);
-+static void externalpipe(const Arg *);
-
- /* config.h for applying patches and the configuration. */
- #include "config.h"
-@@ -2344,6 +2345,62 @@ eschandle(uchar ascii)
- }
-
- void
-+externalpipe(const Arg *arg)
-+{
-+ int to[2]; /* 0 = read, 1 = write */
-+ pid_t child;
-+ int n;
-+ void (*oldsigpipe)(int);
-+ char buf[UTF_SIZ];
-+ Glyph *bp, *end;
-+
-+ if(pipe(to) == -1)
-+ return;
-+
-+ /* sigchld() handles this */
-+ switch(child = fork()){
-+ case -1:
-+ close(to[0]), close(to[1]);
-+ return;
-+ case 0:
-+ /* child */
-+ close(to[1]);
-+ dup2(to[0], STDIN_FILENO); /* 0<&to */
-+ close(to[0]);
-+ execvp(
-+ "sh",
-+ (char *const []){
-+ "/bin/sh",
-+ "-c",
-+ (char *)arg->v,
-+ 0
-+ });
-+ exit(127);
-+ }
-+
-+ /* parent */
-+ close(to[0]);
-+ /* ignore sigpipe for now, in case child exits early */
-+ oldsigpipe = signal(SIGPIPE, SIG_IGN);
-+
-+ for(n = 0; n < term.row; n++){
-+ bp = &term.line[n][0];
-+ end = &bp[MIN(tlinelen(n), term.col) - 1];
-+ if(bp != end || bp->u != ' ')
-+ for(; bp <= end; ++bp)
-+ if(xwrite(to[1], buf, utf8encode(bp->u, buf)) < 0)
-+ break;
-+ if(xwrite(to[1], "\n", 1) < 0)
-+ break;
-+ }
-+
-+ close(to[1]);
-+
-+ /* restore */
-+ signal(SIGPIPE, oldsigpipe);
-+}
-+
-+void
- tputc(Rune u)
- {
- char c[UTF_SIZ];
diff --git a/st.suckless.org/patches/st-externalpipe-20170608-b331da5.diff b/st.suckless.org/patches/st-externalpipe-20170608-b331da5.diff
@@ -0,0 +1,102 @@
+diff --git a/st.c b/st.c
+index 8d4a9f2..3b05f0b 100644
+--- a/st.c
++++ b/st.c
+@@ -138,6 +138,7 @@ static void printscreen(const Arg *) ;
+ static void iso14755(const Arg *);
+ static void toggleprinter(const Arg *);
+ static void sendbreak(const Arg *);
++static void externalpipe(const Arg *);
+
+ /* config.h for applying patches and the configuration. */
+ #include "config.h"
+@@ -2344,6 +2345,59 @@ eschandle(uchar ascii)
+ }
+
+ void
++externalpipe(const Arg *arg)
++{
++ int to[2];
++ char buf[UTF_SIZ];
++ void (*oldsigpipe)(int);
++ Glyph *bp, *end;
++ int lastpos, n, newline;
++
++ if (pipe(to) == -1)
++ return;
++
++ switch (fork()) {
++ case -1:
++ close(to[0]);
++ close(to[1]);
++ return;
++ case 0:
++ dup2(to[0], STDIN_FILENO);
++ close(to[0]);
++ close(to[1]);
++ execvp(((char **)arg->v)[0], (char **)arg->v);
++ fprintf(stderr, "st: execvp %s ", ((char **)arg->v)[0]);
++ perror("failed");
++ exit(0);
++ }
++
++ close(to[0]);
++ /* ignore sigpipe for now, in case child exits early */
++ oldsigpipe = signal(SIGPIPE, SIG_IGN);
++ newline = 0;
++ for (n = 0; n < term.row; n++) {
++ bp = term.line[n];
++ lastpos = MIN(tlinelen(n) + 1, term.col) - 1;
++ if (lastpos < 0)
++ break;
++ end = &bp[lastpos + 1];
++ for (; bp < end; ++bp)
++ if (xwrite(to[1], buf, utf8encode(bp->u, buf)) < 0)
++ break;
++ if (newline = term.line[n][lastpos].mode & ATTR_WRAP)
++ continue;
++ if (xwrite(to[1], "\n", 1) < 0)
++ break;
++ newline = 0;
++ }
++ if (newline)
++ (void)xwrite(to[1], "\n", 1);
++ close(to[1]);
++ /* restore */
++ signal(SIGPIPE, oldsigpipe);
++}
++
++void
+ tputc(Rune u)
+ {
+ char c[UTF_SIZ];
+diff --git a/win.h b/win.h
+index 428111c..a012a24 100644
+--- a/win.h
++++ b/win.h
+@@ -28,3 +28,5 @@ void xresize(int, int);
+ void xselpaste(void);
+ unsigned long xwinid(void);
+ void xsetsel(char *, Time);
++
++extern char winid[64];
+diff --git a/x.c b/x.c
+index fbfd350..ff052e6 100644
+--- a/x.c
++++ b/x.c
+@@ -139,6 +139,7 @@ static void (*handler[LASTEvent])(XEvent *) = {
+ static DC dc;
+ static XWindow xw;
+ static XSelection xsel;
++char winid[64];
+
+ /* Font Ring Cache */
+ enum {
+@@ -915,6 +916,7 @@ xinit(void)
+ win.w, win.h, 0, XDefaultDepth(xw.dpy, xw.scr), InputOutput,
+ xw.vis, CWBackPixel | CWBorderPixel | CWBitGravity
+ | CWEventMask | CWColormap, &xw.attrs);
++ snprintf(winid, LEN(winid), "%lu", (unsigned long)xw.win);
+
+ memset(&gcvalues, 0, sizeof(gcvalues));
+ gcvalues.graphics_exposures = False;