From 1d694a8ec3e8a3aee58ee10514435ec893d70b3b Mon Sep 17 00:00:00 2001 From: speedie Date: Fri, 2 Sep 2022 14:32:45 +0200 Subject: [PATCH] Add externalpipe --- Makefile | 4 ++- config.mk | 2 +- docs/patchlist | 2 ++ external.h | 3 ++ keybinds.h | 1 + scripts/urllist | 1 + st.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++- st.h | 1 + x.c | 1 + 9 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 external.h create mode 100644 scripts/urllist diff --git a/Makefile b/Makefile index 3e36c48..32830c2 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,7 @@ clean: dist: clean mkdir -p st-spde-$(VERSION) - cp -R LICENSE Makefile *.mk *.info *.h *.png *.desktop *.ttf $(SRC)\ + cp -R LICENSE Makefile *.mk *.info *.h *.png *.desktop *.ttf docs scripts $(SRC)\ st-spde-$(VERSION) tar -cf - st-spde-$(VERSION) | gzip > st-spde-$(VERSION).tar.gz rm -rf st-spde-$(VERSION) @@ -48,6 +48,8 @@ install: st [ -f $(ICONNAME) ] && cp -f $(ICONNAME) $(DESTDIR)$(ICONPREFIX) || : mkdir -p $(DESTDIR)$(APPPREFIX) cp -f st.desktop $(DESTDIR)$(APPPREFIX) + cp -f scripts/urllist $(DESTDIR)$(PREFIX)/bin + chmod +x $(DESTDIR)$(PREFIX)/bin/urllist rm -f ./st rm -f *.o diff --git a/config.mk b/config.mk index a73ce3f..da2ea97 100644 --- a/config.mk +++ b/config.mk @@ -4,7 +4,7 @@ VERSION = 0.8.5 # Customize below to fit your system # paths -PREFIX = /usr/local +PREFIX = /usr APPPREFIX = $(PREFIX)/share/applications MANPREFIX = $(PREFIX)/share/man ICONPREFIX = $(PREFIX)/share/pixmaps diff --git a/docs/patchlist b/docs/patchlist index f8aa5c4..2715abd 100644 --- a/docs/patchlist +++ b/docs/patchlist @@ -24,3 +24,5 @@ st-undercurl st-anysize st-xrandrfontsize st-delkey +st-extenralpipe +st-externalpipe-eternal diff --git a/external.h b/external.h new file mode 100644 index 0000000..41a64fd --- /dev/null +++ b/external.h @@ -0,0 +1,3 @@ +/* This is the header used to control extenralpipe. + */ +static char *listurl[] = { "/bin/sh", "-c", "urllist", NULL }; diff --git a/keybinds.h b/keybinds.h index fa5a703..dc9216a 100644 --- a/keybinds.h +++ b/keybinds.h @@ -17,4 +17,5 @@ static Shortcut shortcuts[] = { { TERMMOD, XK_Num_Lock, numlock, {.i = 0} }, { ControlMask|ShiftMask, XK_k, kscrollup, {.i = +1} }, { ControlMask|ShiftMask, XK_j, kscrolldown, {.i = +1} }, + { ControlMask|ShiftMask, XK_U, externalpipe, { .v = listurl } }, }; diff --git a/scripts/urllist b/scripts/urllist new file mode 100644 index 0000000..dc1951e --- /dev/null +++ b/scripts/urllist @@ -0,0 +1 @@ +# temporarily empty diff --git a/st.c b/st.c index 2e0e89d..e473ecf 100644 --- a/st.c +++ b/st.c @@ -53,6 +53,8 @@ : term.line[(y) - term.scr] \ ) +#define TLINE_HIST(y) ((y) <= HISTSIZE-term.row+2 ? term.hist[(y)] : term.line[(y-HISTSIZE+term.row-3)]) + #define TLINEABS(y) ( \ (y) < 0 ? term.hist[(term.histi + (y) + 1 + HISTSIZE) % HISTSIZE] : term.line[(y)] \ ) @@ -521,6 +523,20 @@ tgetline(char *buf, const Glyph *fgp) return ptr - buf; } +int +tlinehistlen(int y) +{ + int i = term.col; + + if (TLINE_HIST(y)[i - 1].mode & ATTR_WRAP) + return i; + + while (i > 0 && TLINE_HIST(y)[i - 1].u == ' ') + --i; + + return i; +} + void selstart(int col, int row, int snap) { @@ -825,8 +841,14 @@ sigchld(int a) if ((p = waitpid(pid, &stat, WNOHANG)) < 0) die("waiting for pid %hd failed: %s\n", pid, strerror(errno)); - if (pid != p) + if (pid != p) { + if (p == 0 && wait(&stat) < 0) + die("wait: %s\n", strerror(errno)); + + /* reinstall sigchld handler */ + signal(SIGCHLD, sigchld); return; + } if (WIFEXITED(stat) && WEXITSTATUS(stat)) die("child exited with status %d\n", WEXITSTATUS(stat)); @@ -2306,6 +2328,61 @@ strparse(void) } } +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\n", ((char **)arg->v)[0]); + perror("failed"); + exit(0); + } + + close(to[0]); + /* ignore sigpipe for now, in case child exists early */ + oldsigpipe = signal(SIGPIPE, SIG_IGN); + newline = 0; + for (n = 0; n <= HISTSIZE + 2; n++) { + bp = TLINE_HIST(n); + lastpos = MIN(tlinehistlen(n) + 1, term.col) - 1; + if (lastpos < 0) + break; + if (lastpos == 0) + continue; + end = &bp[lastpos + 1]; + for (; bp < end; ++bp) + if (xwrite(to[1], buf, utf8encode(bp->u, buf)) < 0) + break; + if ((newline = TLINE_HIST(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 strdump(void) { diff --git a/st.h b/st.h index e8b7a8b..488ace2 100644 --- a/st.h +++ b/st.h @@ -93,6 +93,7 @@ void draw(void); void kscrolldown(const Arg *); void kscrollup(const Arg *); +void externalpipe(const Arg *); void printscreen(const Arg *); void printsel(const Arg *); void sendbreak(const Arg *); diff --git a/x.c b/x.c index bcb9371..9ad9673 100644 --- a/x.c +++ b/x.c @@ -105,6 +105,7 @@ static void ttysend(const Arg *); #define UNDERCURL_CAPPED 2 #include "options.h" /* include user configuration */ +#include "external.h" /* include externalpipe options */ #include "char.h" /* include misc chars */ #ifdef USEXRESOURCES