tabbed-cwd-20230128-41e2b8f.diff - sites - public wiki contents of suckless.org
(HTM) git clone git://git.suckless.org/sites
(DIR) Log
(DIR) Files
(DIR) Refs
---
tabbed-cwd-20230128-41e2b8f.diff (3021B)
---
1 From 50753359eb7a760bcadd54611431c0888867c21c Mon Sep 17 00:00:00 2001
2 From: Casey Fitzpatrick <kcghost@gmail.com>
3 Date: Sat, 28 Jan 2023 09:46:53 -0500
4 Subject: [PATCH] Spawn new tabs in working directory of selected clients child
5
6 When used with st or xterm the working directory of the new tab
7 should be the same as the currently selected tab.
8 ---
9 tabbed.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
10 1 file changed, 56 insertions(+), 1 deletion(-)
11
12 diff --git a/tabbed.c b/tabbed.c
13 index eafe28a..eb046d0 100644
14 --- a/tabbed.c
15 +++ b/tabbed.c
16 @@ -10,6 +10,7 @@
17 #include <stdlib.h>
18 #include <string.h>
19 #include <unistd.h>
20 +#include <linux/limits.h>
21 #include <X11/Xatom.h>
22 #include <X11/Xlib.h>
23 #include <X11/Xproto.h>
24 @@ -84,6 +85,7 @@ typedef struct {
25 int tabx;
26 Bool urgent;
27 Bool closed;
28 + pid_t pid;
29 } Client;
30
31 /* function declarations */
32 @@ -168,6 +170,7 @@ static int cmd_append_pos;
33 static char winid[64];
34 static char **cmd;
35 static char *wmname = "tabbed";
36 +static pid_t nextpid;
37 static const char *geometry;
38
39 char *argv0;
40 @@ -175,6 +178,49 @@ char *argv0;
41 /* configuration, allows nested code to access above variables */
42 #include "config.h"
43
44 +// Given a pid, return its cwd to buf
45 +int getpidcwd(pid_t pid, char* buf, size_t bufsiz) {
46 + static const int proc_max = 20; // '/proc/4194304/cwd'
47 + int sn_ret;
48 + ssize_t rl_ret;
49 + char path[proc_max];
50 +
51 + sn_ret = snprintf(path, proc_max, "/proc/%d/cwd", pid);
52 + if(sn_ret < 0 || sn_ret >= proc_max)
53 + return -1;
54 +
55 + rl_ret = readlink(path, buf, bufsiz);
56 + if(rl_ret < 0 || rl_ret == bufsiz)
57 + return -1;
58 +
59 + buf[rl_ret] = 0;
60 + return 0;
61 +}
62 +
63 +// Given a pid, return a reasonable guess at its child pid
64 +pid_t getchildpid(pid_t pid) {
65 + // '/proc/4194304/task/4194304/children'
66 + static const int proc_max = 40;
67 + int sn_ret;
68 + char path[proc_max];
69 + FILE* f;
70 +
71 + // guessing tid == pid
72 + sn_ret = snprintf(path, proc_max, "/proc/%d/task/%d/children", pid, pid);
73 + if (sn_ret < 0 || sn_ret >= proc_max)
74 + return -1;
75 +
76 + f = fopen(path, "r");
77 + if(f == NULL)
78 + return -1;
79 +
80 + // guess first child
81 + if(fscanf(f, "%d ", &pid) != 1)
82 + return -1;
83 +
84 + return pid;
85 +}
86 +
87 void
88 buttonpress(const XEvent *e)
89 {
90 @@ -725,6 +771,7 @@ manage(Window w)
91
92 c = ecalloc(1, sizeof *c);
93 c->win = w;
94 + c->pid = nextpid;
95
96 nclients++;
97 clients = erealloc(clients, sizeof(Client *) * nclients);
98 @@ -1090,11 +1137,17 @@ sigchld(int unused)
99 void
100 spawn(const Arg *arg)
101 {
102 - if (fork() == 0) {
103 + char sel_cwd[PATH_MAX];
104 +
105 + pid_t pid = fork();
106 + if (pid == 0) {
107 if(dpy)
108 close(ConnectionNumber(dpy));
109
110 setsid();
111 + if (sel >= 0 && clients[sel] && clients[sel]->pid > 0 && getpidcwd(getchildpid(clients[sel]->pid), sel_cwd, PATH_MAX) == 0) {
112 + chdir(sel_cwd);
113 + }
114 if (arg && arg->v) {
115 execvp(((char **)arg->v)[0], (char **)arg->v);
116 fprintf(stderr, "%s: execvp %s", argv0,
117 @@ -1106,6 +1159,8 @@ spawn(const Arg *arg)
118 }
119 perror(" failed");
120 exit(0);
121 + } else {
122 + nextpid = pid;
123 }
124 }
125
126 --
127 2.25.1
128