summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMalfurious <m@lfurio.us>2021-10-03 02:16:10 -0400
committerMatt Hunter <m@lfurio.us>2026-02-06 00:30:19 -0500
commit463771a81b910c4811dd27fc4640206a012e83d6 (patch)
tree66ce188a749f4f0d197032198f8c3c4a353c2a41
parent4ed010694f00b0a3df4d0e48e3da19261d346006 (diff)
downloadst-463771a81b910c4811dd27fc4640206a012e83d6.tar.gz
st-463771a81b910c4811dd27fc4640206a012e83d6.zip
patch: newterm (orphan version)
Ctrl-Shift-Return now creates a new st terminal, whose CWD is the same as the parent st's CWD. This version of the patch does a double fork, a technique commonly used by daemons to spawn orphan processes. This solution is specific to the swallow patch for dwm which traverses the process tree to determine if the new window is a decendant of a terminal window, in which case the new window should take the place of the terminal window. The way the original newterm patch worked the new st terminal would be a direct decendant of the parent st terminal process, which could lead to the wrong terminal window being swallowed. The double fork method avoids this by leaving all new st terminals as orphans, i.e. they will have no parent process.
-rw-r--r--config.def.h1
-rw-r--r--st.c32
-rw-r--r--st.h1
3 files changed, 34 insertions, 0 deletions
diff --git a/config.def.h b/config.def.h
index e7f5a0b..6326287 100644
--- a/config.def.h
+++ b/config.def.h
@@ -204,6 +204,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 291859e..fdd6682 100644
--- a/st.c
+++ b/st.c
@@ -153,6 +153,7 @@ typedef struct {
} STREscape;
static void execsh(char *, char **);
+static char *getcwd_by_pid(pid_t pid);
static void stty(char **);
static void sigchld(int);
static void ttywriteraw(const char *, size_t);
@@ -1056,6 +1057,37 @@ tswapscreen(void)
}
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:
+ res = chdir(getcwd_by_pid(pid));
+ execlp("st", "./st", NULL);
+ break;
+ default:
+ exit(0);
+ }
+ default:
+ wait(NULL);
+ }
+}
+
+static char *getcwd_by_pid(pid_t pid) {
+ char buf[32];
+ snprintf(buf, sizeof buf, "/proc/%d/cwd", pid);
+ return realpath(buf, NULL);
+}
+
+void
tscrolldown(int orig, int n)
{
int i;
diff --git a/st.h b/st.h
index fd3b0d8..f2b03b0 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 *);