1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
diff --git a/config.def.h b/config.def.h
index 91ab8ca..d0343e3 100644
--- a/config.def.h
+++ b/config.def.h
@@ -472,3 +472,9 @@ static char ascii_printable[] =
" !\"#$%&'()*+,-./0123456789:;<=>?"
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
"`abcdefghijklmnopqrstuvwxyz{|}~";
+
+/*
+ * plumb_cmd is run on mouse button 3 click, with first NULL set to
+ * current selection and with cwd set to the cwd of the active shell
+ */
+static char *plumb_cmd[] = {"plumb", "-m", NULL, NULL};
diff --git a/st.c b/st.c
index 51049ba..11756c4 100644
--- a/st.c
+++ b/st.c
@@ -27,6 +27,9 @@
#elif defined(__FreeBSD__) || defined(__DragonFly__)
#include
#endif
+#if defined(__OpenBSD__)
+ #include
+#endif
/* Arbitrary sizes */
#define UTF_INVALID 0xFFFD
@@ -231,6 +234,22 @@ static const uchar utfmask[UTF_SIZ + 1] = {0xC0, 0x80, 0xE0, 0xF0, 0xF8};
static const Rune utfmin[UTF_SIZ + 1] = { 0, 0, 0x80, 0x800, 0x10000};
static const Rune utfmax[UTF_SIZ + 1] = {0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF};
+int
+subprocwd(char *path)
+{
+#if defined(__linux)
+ if (snprintf(path, PATH_MAX, "/proc/%d/cwd", pid) < 0)
+ return -1;
+ return 0;
+#elif defined(__OpenBSD__)
+ size_t sz = PATH_MAX;
+ int name[3] = {CTL_KERN, KERN_PROC_CWD, pid};
+ if (sysctl(name, 3, path, &sz, 0, 0) == -1)
+ return -1;
+ return 0;
+#endif
+}
+
ssize_t
xwrite(int fd, const char *s, size_t len)
{
@@ -810,7 +829,7 @@ ttynew(const char *line, char *cmd, const char *out, char **args)
break;
default:
#ifdef __OpenBSD__
- if (pledge("stdio rpath tty proc", NULL) == -1)
+ if (pledge("stdio rpath tty proc ps exec", NULL) == -1)
die("pledge\n");
#endif
close(s);
diff --git a/st.h b/st.h
index 519b9bd..8255556 100644
--- a/st.h
+++ b/st.h
@@ -111,6 +111,8 @@ void *xmalloc(size_t);
void *xrealloc(void *, size_t);
char *xstrdup(const char *);
+int subprocwd(char *);
+
int xgetcolor(int x, unsigned char *r, unsigned char *g, unsigned char *b);
/* config.h globals */
diff --git a/x.c b/x.c
index cd96575..5d3948a 100644
--- a/x.c
+++ b/x.c
@@ -5,6 +5,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -216,6 +217,7 @@ static void (*handler[LASTEvent])(XEvent *) = {
};
/* Globals */
+static int plumbsel;
static DC dc;
static XWindow xw;
static XSelection xsel;
@@ -694,6 +696,37 @@ xsetsel(char *str)
setsel(str, CurrentTime);
}
+void
+plumbinit()
+{
+ for(plumbsel = 0; plumb_cmd[plumbsel]; plumbsel++);
+}
+
+void
+plumb(char *sel) {
+ if (sel == NULL)
+ return;
+ char cwd[PATH_MAX];
+ pid_t child;
+ if (subprocwd(cwd) != 0)
+ return;
+
+ plumb_cmd[plumbsel] = sel;
+
+ switch(child = fork()) {
+ case -1:
+ return;
+ case 0:
+ if (chdir(cwd) != 0)
+ exit(1);
+ if (execvp(plumb_cmd[0], plumb_cmd) == -1)
+ exit(1);
+ exit(0);
+ default:
+ waitpid(child, NULL, 0);
+ }
+}
+
void
brelease(XEvent *e)
{
@@ -711,6 +744,8 @@ brelease(XEvent *e)
return;
if (e->xbutton.button == Button1)
mousesel(e, 1);
+ else if (e->xbutton.button == Button3)
+ plumb(xsel.primary);
}
void
@@ -2076,6 +2111,7 @@ main(int argc, char *argv[])
} ARGEND;
run:
+ plumbinit();
if (argc > 0) /* eat all remaining arguments */
opt_cmd = argv;
|