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