st-newterm-20220221-0.8.5.diff (2833B)
1 From 063d3eff86c788798d8219a7eb10b39d41f06482 Mon Sep 17 00:00:00 2001 2 From: Santtu Lakkala <inz@inz.fi> 3 Date: Sat, 19 Feb 2022 14:12:02 +0200 4 Subject: [PATCH] Add shortcut to spawn new terminal in the current dir 5 6 Build on bakkeby's doule fork version. Use /proc/self/exe as the binary, 7 and argv[0] as the called name. This allows to have several different 8 st's and running from build tree etc. Also skip the unnecessary readlink 9 part, shell shall do that anyway. Futher mark the pty master as cloexec, 10 so the fd's are not leaked to spawned processes. 11 --- 12 config.def.h | 1 + 13 st.c | 36 ++++++++++++++++++++++++++++++++++++ 14 st.h | 1 + 15 3 files changed, 38 insertions(+) 16 17 diff --git a/config.def.h b/config.def.h 18 index 91ab8ca..7c75246 100644 19 --- a/config.def.h 20 +++ b/config.def.h 21 @@ -201,6 +201,7 @@ static Shortcut shortcuts[] = { 22 { TERMMOD, XK_Y, selpaste, {.i = 0} }, 23 { ShiftMask, XK_Insert, selpaste, {.i = 0} }, 24 { TERMMOD, XK_Num_Lock, numlock, {.i = 0} }, 25 + { TERMMOD, XK_Return, newterm, {.i = 0} }, 26 }; 27 28 /* 29 diff --git a/st.c b/st.c 30 index 51049ba..5d435de 100644 31 --- a/st.c 32 +++ b/st.c 33 @@ -20,6 +20,8 @@ 34 #include "st.h" 35 #include "win.h" 36 37 +extern char *argv0; 38 + 39 #if defined(__linux) 40 #include <pty.h> 41 #elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__) 42 @@ -153,6 +155,7 @@ typedef struct { 43 } STREscape; 44 45 static void execsh(char *, char **); 46 +static int chdir_by_pid(pid_t pid); 47 static void stty(char **); 48 static void sigchld(int); 49 static void ttywriteraw(const char *, size_t); 50 @@ -813,6 +816,7 @@ ttynew(const char *line, char *cmd, const char *out, char **args) 51 if (pledge("stdio rpath tty proc", NULL) == -1) 52 die("pledge\n"); 53 #endif 54 + fcntl(m, F_SETFD, FD_CLOEXEC); 55 close(s); 56 cmdfd = m; 57 signal(SIGCHLD, sigchld); 58 @@ -1061,6 +1065,38 @@ tswapscreen(void) 59 tfulldirt(); 60 } 61 62 +void 63 +newterm(const Arg* a) 64 +{ 65 + int res; 66 + switch (fork()) { 67 + case -1: 68 + die("fork failed: %s\n", strerror(errno)); 69 + break; 70 + case 0: 71 + switch (fork()) { 72 + case -1: 73 + die("fork failed: %s\n", strerror(errno)); 74 + break; 75 + case 0: 76 + chdir_by_pid(pid); 77 + execlp("/proc/self/exe", argv0, NULL); 78 + exit(1); 79 + break; 80 + default: 81 + exit(0); 82 + } 83 + default: 84 + wait(NULL); 85 + } 86 +} 87 + 88 +static int chdir_by_pid(pid_t pid) { 89 + char buf[32]; 90 + snprintf(buf, sizeof buf, "/proc/%ld/cwd", (long)pid); 91 + return chdir(buf); 92 +} 93 + 94 void 95 tscrolldown(int orig, int n) 96 { 97 diff --git a/st.h b/st.h 98 index 519b9bd..fbdad18 100644 99 --- a/st.h 100 +++ b/st.h 101 @@ -81,6 +81,7 @@ void die(const char *, ...); 102 void redraw(void); 103 void draw(void); 104 105 +void newterm(const Arg *); 106 void printscreen(const Arg *); 107 void printsel(const Arg *); 108 void sendbreak(const Arg *); 109 -- 110 2.32.0 111