sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | 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