Introduction
Introduction Statistics Contact Development Disclaimer Help
st-newterm-0.9-tmux.diff - sites - public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log
Files
Refs
---
st-newterm-0.9-tmux.diff (3772B)
---
1 From 6640cf9809086d8cfb2363571d3e71a1a7a9f6bd Mon Sep 17 00:00:00 2001
2 From: meator <[email protected]>
3 Date: Tue, 25 Oct 2022 20:19:28 +0200
4 Subject: [PATCH] Add support for tmux in newterm
5
6 This commit tries to figure out if st's child is tmux and if so, it
7 launches a shell with the CWD of the current process in the tmux session
8 instead of the tmux client itself.
9
10 This is heavily inspired by
11 https://gist.github.com/TiddoLangerak/c61e1e48df91192f9554 (but
12 converted to C).
13
14 Tmux has to be a direct child of st. This means that you'll have to
15 usually use the 'exec' shell builtin to attach tmux sessions.
16
17 This patch only works on Linux. Other systems use different procfs which
18 is incompatible or don't have procfs at all (or it's optional).
19 ---
20 st.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
21 1 file changed, 82 insertions(+), 1 deletion(-)
22
23 diff --git a/st.c b/st.c
24 index 0261283..b95bf7a 100644
25 --- a/st.c
26 +++ b/st.c
27 @@ -221,6 +221,8 @@ static char base64dec_getc(const char **);
28
29 static ssize_t xwrite(int, const char *, size_t);
30
31 +static int gettmuxpts(void);
32 +
33 /* Globals */
34 static Term term;
35 static Selection sel;
36 @@ -1061,6 +1063,12 @@ tswapscreen(void)
37 void
38 newterm(const Arg* a)
39 {
40 + int pts;
41 + FILE *fsession, *fpid;
42 + char session[5];
43 + char pidstr[10];
44 + char buf[48];
45 + size_t size;
46 switch (fork()) {
47 case -1:
48 die("fork failed: %s\n", strerror(errno));
49 @@ -1072,7 +1080,37 @@ newterm(const Arg* a)
50 _exit(1);
51 break;
52 case 0:
53 - chdir_by_pid(pid);
54 + signal(SIGCHLD, SIG_DFL); /* pclose() needs to …
55 + pts = gettmuxpts();
56 + if (pts != -1) {
57 + snprintf(buf, sizeof buf, "tmux lsc -t …
58 + fsession = popen(buf, "r");
59 + if (!fsession) {
60 + fprintf(stderr, "Couldn't launc…
61 + _exit(1);
62 + }
63 + size = fread(session, 1, sizeof session…
64 + if (pclose(fsession) != 0 || size == 0)…
65 + fprintf(stderr, "Couldn't get t…
66 + _exit(1);
67 + }
68 + session[size - 1] = '\0'; /* size - 1 i…
69 +
70 + snprintf(buf, sizeof buf, "tmux list-pa…
71 + fpid = popen(buf, "r");
72 + if (!fpid) {
73 + fprintf(stderr, "Couldn't launc…
74 + _exit(1);
75 + }
76 + size = fread(pidstr, 1, sizeof pidstr, …
77 + if (pclose(fpid) != 0 || size == 0) {
78 + fprintf(stderr, "Couldn't get t…
79 + _exit(1);
80 + }
81 + pidstr[size - 1] = '\0';
82 + }
83 +
84 + chdir_by_pid(pts != -1 ? atol(pidstr) : pid);
85 execl("/proc/self/exe", argv0, NULL);
86 _exit(1);
87 break;
88 @@ -1092,6 +1130,49 @@ chdir_by_pid(pid_t pid)
89 return chdir(buf);
90 }
91
92 +/* returns the pty of tmux client or -1 if the child of st isn't tmux */
93 +static int
94 +gettmuxpts(void)
95 +{
96 + char buf[32];
97 + char comm[17];
98 + int tty;
99 + FILE *fstat;
100 + FILE *fcomm;
101 + size_t numread;
102 +
103 + snprintf(buf, sizeof buf, "/proc/%ld/comm", (long)pid);
104 +
105 + fcomm = fopen(buf, "r");
106 + if (!fcomm) {
107 + fprintf(stderr, "Couldn't open %s: %s\n", buf, strerror…
108 + _exit(1);
109 + }
110 +
111 + numread = fread(comm, 1, sizeof comm - 1, fcomm);
112 + comm[numread] = '\0';
113 +
114 + fclose(fcomm);
115 +
116 + if (strcmp("tmux: client\n", comm) != 0)
117 + return -1;
118 +
119 + snprintf(buf, sizeof buf, "/proc/%ld/stat", (long)pid);
120 + fstat = fopen(buf, "r");
121 + if (!fstat) {
122 + fprintf(stderr, "Couldn't open %s: %s\n", buf, strerror…
123 + _exit(1);
124 + }
125 +
126 + /*
127 + * We can't skip the second field with %*s because it contains …
128 + * we skip strlen("tmux: client") + 2 for the braces which is 1…
129 + */
130 + fscanf(fstat, "%*d %*14c %*c %*d %*d %*d %d", &tty);
131 + fclose(fstat);
132 + return ((0xfff00000 & tty) >> 12) | (0xff & tty);
133 +}
134 +
135 void
136 tscrolldown(int orig, int n)
137 {
138 --
139 2.38.0
140
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.