diff options
Diffstat (limited to 'st/patches/st-newterm-0.9-tmux.diff')
| -rw-r--r-- | st/patches/st-newterm-0.9-tmux.diff | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/st/patches/st-newterm-0.9-tmux.diff b/st/patches/st-newterm-0.9-tmux.diff new file mode 100644 index 0000000..cd73e60 --- /dev/null +++ b/st/patches/st-newterm-0.9-tmux.diff @@ -0,0 +1,140 @@ +From 6640cf9809086d8cfb2363571d3e71a1a7a9f6bd Mon Sep 17 00:00:00 2001 +From: meator <meator.dev@gmail.com> +Date: Tue, 25 Oct 2022 20:19:28 +0200 +Subject: [PATCH] Add support for tmux in newterm + +This commit tries to figure out if st's child is tmux and if so, it +launches a shell with the CWD of the current process in the tmux session +instead of the tmux client itself. + +This is heavily inspired by +https://gist.github.com/TiddoLangerak/c61e1e48df91192f9554 (but +converted to C). + +Tmux has to be a direct child of st. This means that you'll have to +usually use the 'exec' shell builtin to attach tmux sessions. + +This patch only works on Linux. Other systems use different procfs which +is incompatible or don't have procfs at all (or it's optional). +--- + st.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 82 insertions(+), 1 deletion(-) + +diff --git a/st.c b/st.c +index 0261283..b95bf7a 100644 +--- a/st.c ++++ b/st.c +@@ -221,6 +221,8 @@ static char base64dec_getc(const char **); + + static ssize_t xwrite(int, const char *, size_t); + ++static int gettmuxpts(void); ++ + /* Globals */ + static Term term; + static Selection sel; +@@ -1061,6 +1063,12 @@ tswapscreen(void) + void + newterm(const Arg* a) + { ++ int pts; ++ FILE *fsession, *fpid; ++ char session[5]; ++ char pidstr[10]; ++ char buf[48]; ++ size_t size; + switch (fork()) { + case -1: + die("fork failed: %s\n", strerror(errno)); +@@ -1072,7 +1080,37 @@ newterm(const Arg* a) + _exit(1); + break; + case 0: +- chdir_by_pid(pid); ++ signal(SIGCHLD, SIG_DFL); /* pclose() needs to use wait() */ ++ pts = gettmuxpts(); ++ if (pts != -1) { ++ snprintf(buf, sizeof buf, "tmux lsc -t /dev/pts/%d -F \"#{client_session}\"", pts); ++ fsession = popen(buf, "r"); ++ if (!fsession) { ++ fprintf(stderr, "Couldn't launch tmux."); ++ _exit(1); ++ } ++ size = fread(session, 1, sizeof session, fsession); ++ if (pclose(fsession) != 0 || size == 0) { ++ fprintf(stderr, "Couldn't get tmux session."); ++ _exit(1); ++ } ++ session[size - 1] = '\0'; /* size - 1 is used to also trim the \n */ ++ ++ snprintf(buf, sizeof buf, "tmux list-panes -st %s -F \"#{pane_pid}\"", session); ++ fpid = popen(buf, "r"); ++ if (!fpid) { ++ fprintf(stderr, "Couldn't launch tmux."); ++ _exit(1); ++ } ++ size = fread(pidstr, 1, sizeof pidstr, fpid); ++ if (pclose(fpid) != 0 || size == 0) { ++ fprintf(stderr, "Couldn't get tmux session."); ++ _exit(1); ++ } ++ pidstr[size - 1] = '\0'; ++ } ++ ++ chdir_by_pid(pts != -1 ? atol(pidstr) : pid); + execl("/proc/self/exe", argv0, NULL); + _exit(1); + break; +@@ -1092,6 +1130,49 @@ chdir_by_pid(pid_t pid) + return chdir(buf); + } + ++/* returns the pty of tmux client or -1 if the child of st isn't tmux */ ++static int ++gettmuxpts(void) ++{ ++ char buf[32]; ++ char comm[17]; ++ int tty; ++ FILE *fstat; ++ FILE *fcomm; ++ size_t numread; ++ ++ snprintf(buf, sizeof buf, "/proc/%ld/comm", (long)pid); ++ ++ fcomm = fopen(buf, "r"); ++ if (!fcomm) { ++ fprintf(stderr, "Couldn't open %s: %s\n", buf, strerror(errno)); ++ _exit(1); ++ } ++ ++ numread = fread(comm, 1, sizeof comm - 1, fcomm); ++ comm[numread] = '\0'; ++ ++ fclose(fcomm); ++ ++ if (strcmp("tmux: client\n", comm) != 0) ++ return -1; ++ ++ snprintf(buf, sizeof buf, "/proc/%ld/stat", (long)pid); ++ fstat = fopen(buf, "r"); ++ if (!fstat) { ++ fprintf(stderr, "Couldn't open %s: %s\n", buf, strerror(errno)); ++ _exit(1); ++ } ++ ++ /* ++ * We can't skip the second field with %*s because it contains a space so ++ * we skip strlen("tmux: client") + 2 for the braces which is 14. ++ */ ++ fscanf(fstat, "%*d %*14c %*c %*d %*d %*d %d", &tty); ++ fclose(fstat); ++ return ((0xfff00000 & tty) >> 12) | (0xff & tty); ++} ++ + void + tscrolldown(int orig, int n) + { +-- +2.38.0 + |
