Hi,
I've just pushed to the wiki and attached to this message[1] an updated
externalpipe patch (which I find very useful in combination with dmenu
for fishing links and the like).
One version applies cleanly to master and one to 0.6.
As a bonus, both handle utf8 chars correctly.
cheers
--s
[1]: not sure whether this plays well with the new mailing list
separation. apparently they will end up in both wiki@ and hackers@, but
well, they modify the wiki and are patches, so kinda makes sense. let me
know if this is a sin.
diff --git a/config.def.h b/config.def.h
index 64e75b8..9245814 100644
--- a/config.def.h
+++ b/config.def.h
@@ -128,6 +128,7 @@ static Shortcut shortcuts[] = {
{ MODKEY|ShiftMask, XK_C, clipcopy, {.i = 0} },
{ MODKEY|ShiftMask, XK_V, clippaste, {.i = 0} },
{ MODKEY, XK_Num_Lock, numlock, {.i = 0} },
+ { MODKEY, XK_u, externalpipe, {.v = "rot13 >
/tmp/test-externalpipe.txt"} },
};
/*
diff --git a/st.c b/st.c
index b89d094..941deb5 100644
--- a/st.c
+++ b/st.c
@@ -326,6 +326,7 @@ static void clipcopy(const Arg *);
static void clippaste(const Arg *);
static void numlock(const Arg *);
static void selpaste(const Arg *);
+static void externalpipe(const Arg *);
static void xzoom(const Arg *);
static void xzoomabs(const Arg *);
static void xzoomreset(const Arg *);
@@ -2684,6 +2685,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];
bool control;
diff --git a/st.c b/st.c
index 35a840b..bb2dd17 100644
--- a/st.c
+++ b/st.c
@@ -327,6 +327,7 @@ static void clipcopy(const Arg *);
static void clippaste(const Arg *);
static void numlock(const Arg *);
static void selpaste(const Arg *);
+static void externalpipe(const Arg *);
static void xzoom(const Arg *);
static void xzoomabs(const Arg *);
static void xzoomreset(const Arg *);
@@ -2888,6 +2889,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];