plumb_without_shell_OSC.diff (3023B)
1 config.def.h | 6 ++++++ 2 st.c | 21 ++++++++++++++++++++- 3 st.h | 2 ++ 4 x.c | 26 ++++++++++++++++++++++++++ 5 4 files changed, 54 insertions(+), 1 deletion(-) 6 7 diff --git a/config.def.h b/config.def.h 8 index 823e79f..08e6ed4 100644 9 --- a/config.def.h 10 +++ b/config.def.h 11 @@ -459,3 +459,9 @@ static char ascii_printable[] = 12 " !\"#$%&'()*+,-./0123456789:;<=>?" 13 "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" 14 "`abcdefghijklmnopqrstuvwxyz{|}~"; 15 + 16 +/* 17 + * plumb_cmd is run on mouse button 3 click, with argument set to 18 + * current selection and with cwd set to the cwd of the active shell 19 + */ 20 +static char *plumb_cmd = "plumb"; 21 diff --git a/st.c b/st.c 22 index 46cf2da..46d7c8a 100644 23 --- a/st.c 24 +++ b/st.c 25 @@ -27,6 +27,9 @@ 26 #elif defined(__FreeBSD__) || defined(__DragonFly__) 27 #include <libutil.h> 28 #endif 29 +#if defined(__OpenBSD__) 30 + #include <sys/sysctl.h> 31 +#endif 32 33 /* Arbitrary sizes */ 34 #define UTF_INVALID 0xFFFD 35 @@ -232,6 +235,22 @@ static uchar utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8}; 36 static Rune utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000}; 37 static Rune utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF}; 38 39 +int 40 +subprocwd(char *path) 41 +{ 42 +#if defined(__linux) 43 + if (snprintf(path, PATH_MAX, "/proc/%d/cwd", pid) < 0) 44 + return -1; 45 + return 0; 46 +#elif defined(__OpenBSD__) 47 + size_t sz = PATH_MAX; 48 + int name[3] = {CTL_KERN, KERN_PROC_CWD, pid}; 49 + if (sysctl(name, 3, path, &sz, 0, 0) == -1) 50 + return -1; 51 + return 0; 52 +#endif 53 +} 54 + 55 ssize_t 56 xwrite(int fd, const char *s, size_t len) 57 { 58 @@ -810,7 +829,7 @@ ttynew(char *line, char *cmd, char *out, char **args) 59 break; 60 default: 61 #ifdef __OpenBSD__ 62 - if (pledge("stdio rpath tty proc", NULL) == -1) 63 + if (pledge("stdio rpath tty proc ps exec", NULL) == -1) 64 die("pledge\n"); 65 #endif 66 close(s); 67 diff --git a/st.h b/st.h 68 index 38c61c4..1f87287 100644 69 --- a/st.h 70 +++ b/st.h 71 @@ -110,6 +110,8 @@ void *xmalloc(size_t); 72 void *xrealloc(void *, size_t); 73 char *xstrdup(char *); 74 75 +int subprocwd(char *); 76 + 77 /* config.h globals */ 78 extern char *utmp; 79 extern char *stty_args; 80 diff --git a/x.c b/x.c 81 index 00cb6b1..e03dc71 100644 82 --- a/x.c 83 +++ b/x.c 84 @@ -5,6 +5,7 @@ 85 #include <locale.h> 86 #include <signal.h> 87 #include <sys/select.h> 88 +#include <sys/wait.h> 89 #include <time.h> 90 #include <unistd.h> 91 #include <libgen.h> 92 @@ -635,6 +636,29 @@ xsetsel(char *str) 93 setsel(str, CurrentTime); 94 } 95 96 +void 97 +plumb(char *sel) { 98 + if (sel == NULL) 99 + return; 100 + char cwd[PATH_MAX]; 101 + pid_t child; 102 + if (subprocwd(cwd) != 0) 103 + return; 104 + 105 + switch(child = fork()) { 106 + case -1: 107 + return; 108 + case 0: 109 + if (chdir(cwd) != 0) 110 + exit(1); 111 + if (execvp(plumb_cmd, (char *const []){plumb_cmd, sel, 0}) == -1) 112 + exit(1); 113 + exit(0); 114 + default: 115 + waitpid(child, NULL, 0); 116 + } 117 +} 118 + 119 void 120 brelease(XEvent *e) 121 { 122 @@ -647,6 +671,8 @@ brelease(XEvent *e) 123 selpaste(NULL); 124 else if (e->xbutton.button == Button1) 125 mousesel(e, 1); 126 + else if (e->xbutton.button == Button3) 127 + plumb(xsel.primary); 128 } 129 130 void