st-newterm-orphan-20210712-4536f46.diff - sites - public wiki contents of suckl… | |
git clone git://git.suckless.org/sites | |
Log | |
Files | |
Refs | |
--- | |
st-newterm-orphan-20210712-4536f46.diff (2785B) | |
--- | |
1 From e6ac257f362f8b879b62225bedca9e8aafef4f3b Mon Sep 17 00:00:00 2001 | |
2 From: bakkeby <[email protected]> | |
3 Date: Mon, 12 Jul 2021 09:35:04 +0200 | |
4 Subject: [PATCH] Add shortcut to spawn new terminal in the current dir | |
5 | |
6 Ctrl-Shift-Return now creates a new ST terminal, whose CWD is the same | |
7 as the parent st's CWD. | |
8 | |
9 This version of the patch does a double fork, a technique commonly used | |
10 by daemons to spawn orphan processes. | |
11 | |
12 This solution is specific to the swallow patch for dwm which traverses | |
13 the process tree to determine if the new window is a decendant of a | |
14 terminal window, in which case the new window should take the place of | |
15 the terminal window. | |
16 | |
17 The way the original newterm patch worked the new st terminal would be | |
18 a direct decendant of the parent st terminal process, which could lead | |
19 to the wrong terminal window being swallowed. | |
20 | |
21 The double fork method avoids this by leaving all new st terminals as | |
22 orphans, i.e. they will have no parent process. | |
23 --- | |
24 config.def.h | 1 + | |
25 st.c | 32 ++++++++++++++++++++++++++++++++ | |
26 st.h | 1 + | |
27 3 files changed, 34 insertions(+) | |
28 | |
29 diff --git a/config.def.h b/config.def.h | |
30 index 6f05dce..9029e8d 100644 | |
31 --- a/config.def.h | |
32 +++ b/config.def.h | |
33 @@ -199,6 +199,7 @@ static Shortcut shortcuts[] = { | |
34 { TERMMOD, XK_Y, selpaste, {.i = … | |
35 { ShiftMask, XK_Insert, selpaste, {.i = … | |
36 { TERMMOD, XK_Num_Lock, numlock, {.i = … | |
37 + { TERMMOD, XK_Return, newterm, {.i = … | |
38 }; | |
39 | |
40 /* | |
41 diff --git a/st.c b/st.c | |
42 index ebdf360..cb79bc0 100644 | |
43 --- a/st.c | |
44 +++ b/st.c | |
45 @@ -153,6 +153,7 @@ typedef struct { | |
46 } STREscape; | |
47 | |
48 static void execsh(char *, char **); | |
49 +static char *getcwd_by_pid(pid_t pid); | |
50 static void stty(char **); | |
51 static void sigchld(int); | |
52 static void ttywriteraw(const char *, size_t); | |
53 @@ -1060,6 +1061,37 @@ tswapscreen(void) | |
54 tfulldirt(); | |
55 } | |
56 | |
57 +void | |
58 +newterm(const Arg* a) | |
59 +{ | |
60 + int res; | |
61 + switch (fork()) { | |
62 + case -1: | |
63 + die("fork failed: %s\n", strerror(errno)); | |
64 + break; | |
65 + case 0: | |
66 + switch (fork()) { | |
67 + case -1: | |
68 + die("fork failed: %s\n", strerror(errno)); | |
69 + break; | |
70 + case 0: | |
71 + res = chdir(getcwd_by_pid(pid)); | |
72 + execlp("st", "./st", NULL); | |
73 + break; | |
74 + default: | |
75 + exit(0); | |
76 + } | |
77 + default: | |
78 + wait(NULL); | |
79 + } | |
80 +} | |
81 + | |
82 +static char *getcwd_by_pid(pid_t pid) { | |
83 + char buf[32]; | |
84 + snprintf(buf, sizeof buf, "/proc/%d/cwd", pid); | |
85 + return realpath(buf, NULL); | |
86 +} | |
87 + | |
88 void | |
89 tscrolldown(int orig, int n) | |
90 { | |
91 diff --git a/st.h b/st.h | |
92 index fa2eddf..b13399b 100644 | |
93 --- a/st.h | |
94 +++ b/st.h | |
95 @@ -81,6 +81,7 @@ void die(const char *, ...); | |
96 void redraw(void); | |
97 void draw(void); | |
98 | |
99 +void newterm(const Arg *); | |
100 void printscreen(const Arg *); | |
101 void printsel(const Arg *); | |
102 void sendbreak(const Arg *); | |
103 -- | |
104 2.32.0 | |
105 |