From 063d3eff86c788798d8219a7eb10b39d41f06482 Mon Sep 17 00:00:00 2001 From: Santtu Lakkala Date: Sat, 19 Feb 2022 14:12:02 +0200 Subject: [PATCH] Add shortcut to spawn new terminal in the current dir Build on bakkeby's doule fork version. Use /proc/self/exe as the binary, and argv[0] as the called name. This allows to have several different st's and running from build tree etc. Also skip the unnecessary readlink part, shell shall do that anyway. Futher mark the pty master as cloexec, so the fd's are not leaked to spawned processes. --- config.def.h | 1 + st.c | 36 ++++++++++++++++++++++++++++++++++++ st.h | 1 + 3 files changed, 38 insertions(+) diff --git a/config.def.h b/config.def.h index 91ab8ca..7c75246 100644 --- a/config.def.h +++ b/config.def.h @@ -201,6 +201,7 @@ static Shortcut shortcuts[] = { { TERMMOD, XK_Y, selpaste, {.i = 0} }, { ShiftMask, XK_Insert, selpaste, {.i = 0} }, { TERMMOD, XK_Num_Lock, numlock, {.i = 0} }, + { TERMMOD, XK_Return, newterm, {.i = 0} }, }; /* diff --git a/st.c b/st.c index 51049ba..5d435de 100644 --- a/st.c +++ b/st.c @@ -20,6 +20,8 @@ #include "st.h" #include "win.h" +extern char *argv0; + #if defined(__linux) #include #elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__) @@ -153,6 +155,7 @@ typedef struct { } STREscape; 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); @@ -813,6 +816,7 @@ ttynew(const char *line, char *cmd, const char *out, char **args) if (pledge("stdio rpath tty proc", NULL) == -1) die("pledge\n"); #endif + fcntl(m, F_SETFD, FD_CLOEXEC); close(s); cmdfd = m; signal(SIGCHLD, sigchld); @@ -1061,6 +1065,38 @@ tswapscreen(void) tfulldirt(); } +void +newterm(const Arg* a) +{ + int res; + 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("/proc/self/exe", 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 tscrolldown(int orig, int n) { diff --git a/st.h b/st.h index 519b9bd..fbdad18 100644 --- 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 printscreen(const Arg *); void printsel(const Arg *); void sendbreak(const Arg *); -- 2.32.0