diff --git a/tabbed.c b/tabbed.c index aa45716..e4c5f90 100644 --- a/tabbed.c +++ b/tabbed.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -85,6 +86,7 @@ typedef struct { int tabx; Bool urgent; Bool closed; + pid_t pid; } Client; /* function declarations */ @@ -168,6 +170,7 @@ static int cmd_append_pos; static char winid[64]; static char **cmd; static char *wmname = "tabbed"; +static pid_t nextpid; static const char *geometry; char *argv0; @@ -175,6 +178,49 @@ char *argv0; /* configuration, allows nested code to access above variables */ #include "config.h" +// Given a pid, return its cwd to buf +int getpidcwd(pid_t pid, char* buf, size_t bufsiz) { + static const int proc_max = 20; // '/proc/4194304/cwd' + int sn_ret; + ssize_t rl_ret; + char path[proc_max]; + + sn_ret = snprintf(path, proc_max, "/proc/%d/cwd", pid); + if(sn_ret < 0 || sn_ret >= proc_max) + return -1; + + rl_ret = readlink(path, buf, bufsiz); + if(rl_ret < 0 || rl_ret == bufsiz) + return -1; + + buf[rl_ret] = 0; + return 0; +} + +// Given a pid, return a reasonable guess at its child pid +pid_t getchildpid(pid_t pid) { + // '/proc/4194304/task/4194304/children' + static const int proc_max = 40; + int sn_ret; + char path[proc_max]; + FILE* f; + + // guessing tid == pid + sn_ret = snprintf(path, proc_max, "/proc/%d/task/%d/children", pid, pid); + if (sn_ret < 0 || sn_ret >= proc_max) + return -1; + + f = fopen(path, "r"); + if(f == NULL) + return -1; + + // guess first child + if(fscanf(f, "%d ", &pid) != 1) + return -1; + + return pid; +} + void buttonpress(const XEvent *e) { @@ -737,6 +783,7 @@ manage(Window w) c = ecalloc(1, sizeof *c); c->win = w; + c->pid = nextpid; nclients++; clients = erealloc(clients, sizeof(Client *) * nclients); @@ -1102,11 +1149,17 @@ spawn(const Arg *arg) { struct sigaction sa; - if (fork() == 0) { + char sel_cwd[PATH_MAX]; + + pid_t pid = fork(); + if (pid == 0) { if(dpy) close(ConnectionNumber(dpy)); setsid(); + if (sel >= 0 && clients[sel] && clients[sel]->pid > 0 && getpidcwd(getchildpid(clients[sel]->pid), sel_cwd, PATH_MAX) == 0) { + chdir(sel_cwd); + } sigemptyset(&sa.sa_mask); sa.sa_flags = 0; @@ -1124,6 +1177,8 @@ spawn(const Arg *arg) } perror(" failed"); exit(0); + } else { + nextpid = pid; } } -- 2.51.0