st

Patched version of https://st.suckless.org/
git clone https://git.inz.fi/st/
Log | Files | Refs | README | LICENSE

commit 5e68370e8221e299da6e91dab094227ff0bd700f
parent fea256adad59d0e657544c55357eff038af99281
Author: Santtu Lakkala <inz@inz.fi>
Date:   Sat, 19 Feb 2022 14:12:02 +0200

Function to spawn new terminal in the current dir

Build on bakkeby's doule fork version. Use readlink on /proc/self/exe as
the binary, and argv[0] as argv[0]. This allows to have several different
st's and running from build tree etc. Also skip the unnecessary readlink
on current directory. Futher mark the pty master as cloexec, so the fd
is not leaked to spawned processes.

Diffstat:
Mconfig.def.h | 1+
Mst.c | 40++++++++++++++++++++++++++++++++++++++++
Mst.h | 1+
3 files changed, 42 insertions(+), 0 deletions(-)

diff --git a/config.def.h b/config.def.h @@ -208,6 +208,7 @@ static Shortcut shortcuts[] = { { MODKEY, XK_o, opencopied, {.v = "xdg-open"} }, { ShiftMask, XK_Page_Up, kscrollup, {.i = -1} }, { ShiftMask, XK_Page_Down, kscrolldown, {.i = -1} }, + { TERMMOD, XK_Return, newterm, {.i = 0} }, }; /* diff --git a/st.c b/st.c @@ -20,6 +20,8 @@ #include "st.h" #include "win.h" +extern char *argv0; + #if defined(__linux) #include <pty.h> #elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__) @@ -165,6 +167,7 @@ typedef struct { } URLdfa; static void execsh(char *, char **); +static int chdir_by_pid(pid_t pid); static void stty(char **); static void sigchld(int); static void ttywriteraw(const char *, size_t); @@ -826,6 +829,7 @@ ttynew(const char *line, char *cmd, const char *out, char **args) if (pledge("stdio rpath tty proc exec", NULL) == -1) die("pledge\n"); #endif + fcntl(m, F_SETFD, FD_CLOEXEC); close(s); cmdfd = m; signal(SIGCHLD, sigchld); @@ -1078,6 +1082,42 @@ tswapscreen(void) } void +newterm(const Arg* a) +{ + char bin[PATH_MAX]; + + if (readlink("/proc/self/exe", bin, sizeof(bin)) < 0) + return; + + switch (fork()) { + case -1: + die("fork failed: %s\n", strerror(errno)); + break; + case 0: + switch (fork()) { + case -1: + die("fork failed: %s\n", strerror(errno)); + break; + case 0: + chdir_by_pid(pid); + execlp(bin, argv0, NULL); + exit(1); + break; + default: + exit(0); + } + default: + wait(NULL); + } +} + +static int chdir_by_pid(pid_t pid) { + char buf[32]; + snprintf(buf, sizeof buf, "/proc/%ld/cwd", (long)pid); + return chdir(buf); +} + +void kscrolldown(const Arg* a) { int n = a->i; diff --git a/st.h b/st.h @@ -81,6 +81,7 @@ void die(const char *, ...); void redraw(void); void draw(void); +void newterm(const Arg *); void kscrolldown(const Arg *); void kscrollup(const Arg *); void opencopied(const Arg *);