sites

public wiki contents of suckless.org
git clone git://git.suckless.org/sites
Log | Files | Refs

st-newterm-orphan-20210712-4536f46.diff (2785B)


      1 From e6ac257f362f8b879b62225bedca9e8aafef4f3b Mon Sep 17 00:00:00 2001
      2 From: bakkeby <bakkeby@gmail.com>
      3 Date: Mon, 12 Jul 2021 09:35:04 +0200
      4 Subject: [PATCH] Add shortcut to spawn new terminal in the current dir
      5 
      6 Ctrl-Shift-Return now creates a new ST terminal, whose CWD is the same
      7 as the parent st's CWD.
      8 
      9 This version of the patch does a double fork, a technique commonly used
     10 by daemons to spawn orphan processes.
     11 
     12 This solution is specific to the swallow patch for dwm which traverses
     13 the process tree to determine if the new window is a decendant of a
     14 terminal window, in which case the new window should take the place of
     15 the terminal window.
     16 
     17 The way the original newterm patch worked the new st terminal would be
     18 a direct decendant of the parent st terminal process, which could lead
     19 to the wrong terminal window being swallowed.
     20 
     21 The double fork method avoids this by leaving all new st terminals as
     22 orphans, i.e. they will have no parent process.
     23 ---
     24  config.def.h |  1 +
     25  st.c         | 32 ++++++++++++++++++++++++++++++++
     26  st.h         |  1 +
     27  3 files changed, 34 insertions(+)
     28 
     29 diff --git a/config.def.h b/config.def.h
     30 index 6f05dce..9029e8d 100644
     31 --- a/config.def.h
     32 +++ b/config.def.h
     33 @@ -199,6 +199,7 @@ static Shortcut shortcuts[] = {
     34  	{ TERMMOD,              XK_Y,           selpaste,       {.i =  0} },
     35  	{ ShiftMask,            XK_Insert,      selpaste,       {.i =  0} },
     36  	{ TERMMOD,              XK_Num_Lock,    numlock,        {.i =  0} },
     37 +	{ TERMMOD,              XK_Return,      newterm,        {.i =  0} },
     38  };
     39  
     40  /*
     41 diff --git a/st.c b/st.c
     42 index ebdf360..cb79bc0 100644
     43 --- a/st.c
     44 +++ b/st.c
     45 @@ -153,6 +153,7 @@ typedef struct {
     46  } STREscape;
     47  
     48  static void execsh(char *, char **);
     49 +static char *getcwd_by_pid(pid_t pid);
     50  static void stty(char **);
     51  static void sigchld(int);
     52  static void ttywriteraw(const char *, size_t);
     53 @@ -1060,6 +1061,37 @@ tswapscreen(void)
     54  	tfulldirt();
     55  }
     56  
     57 +void
     58 +newterm(const Arg* a)
     59 +{
     60 +	int res;
     61 +	switch (fork()) {
     62 +	case -1:
     63 +		die("fork failed: %s\n", strerror(errno));
     64 +		break;
     65 +	case 0:
     66 +		switch (fork()) {
     67 +		case -1:
     68 +			die("fork failed: %s\n", strerror(errno));
     69 +			break;
     70 +		case 0:
     71 +			res = chdir(getcwd_by_pid(pid));
     72 +			execlp("st", "./st", NULL);
     73 +			break;
     74 +		default:
     75 +			exit(0);
     76 +		}
     77 +	default:
     78 +		wait(NULL);
     79 +	}
     80 +}
     81 +
     82 +static char *getcwd_by_pid(pid_t pid) {
     83 +	char buf[32];
     84 +	snprintf(buf, sizeof buf, "/proc/%d/cwd", pid);
     85 +	return realpath(buf, NULL);
     86 +}
     87 +
     88  void
     89  tscrolldown(int orig, int n)
     90  {
     91 diff --git a/st.h b/st.h
     92 index fa2eddf..b13399b 100644
     93 --- a/st.h
     94 +++ b/st.h
     95 @@ -81,6 +81,7 @@ void die(const char *, ...);
     96  void redraw(void);
     97  void draw(void);
     98  
     99 +void newterm(const Arg *);
    100  void printscreen(const Arg *);
    101  void printsel(const Arg *);
    102  void sendbreak(const Arg *);
    103 -- 
    104 2.32.0
    105