mirror of
https://github.com/tmate-io/tmate.git
synced 2026-01-23 02:24:06 +00:00
Compare commits
543 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ac919516f4 | ||
|
|
6cb27ead4e | ||
|
|
15001bfa77 | ||
|
|
3efc8496cc | ||
|
|
2ff8bc134d | ||
|
|
9a1aa9ae9d | ||
|
|
17fcc8b76d | ||
|
|
7c0bbf3e16 | ||
|
|
05a849ba2b | ||
|
|
fde4b58228 | ||
|
|
17d4a8a7df | ||
|
|
ef11a7b30e | ||
|
|
577e04df6c | ||
|
|
b1079b4393 | ||
|
|
a258907cf8 | ||
|
|
169eb64b99 | ||
|
|
be4a88507e | ||
|
|
c9ec7af632 | ||
|
|
808b564564 | ||
|
|
e5ce3f04d2 | ||
|
|
8123fa34f8 | ||
|
|
f6a4ae6042 | ||
|
|
cbec43f56d | ||
|
|
339e6c4357 | ||
|
|
9e3e39d66d | ||
|
|
ba6ac3a363 | ||
|
|
46564a0311 | ||
|
|
cc01f3f13a | ||
|
|
f0a4707ef3 | ||
|
|
5e00bfa5e1 | ||
|
|
f895fe01b1 | ||
|
|
9fe8b32293 | ||
|
|
7e02dba7ef | ||
|
|
bfa3c104d7 | ||
|
|
e5f6e68fad | ||
|
|
9fc6e96444 | ||
|
|
86ec8d1ad6 | ||
|
|
2b86031308 | ||
|
|
2b14611544 | ||
|
|
d3c8808b0f | ||
|
|
8b62c54748 | ||
|
|
ba860b8f45 | ||
|
|
1600a81e58 | ||
|
|
0272757aa5 | ||
|
|
9781946a70 | ||
|
|
442143cd90 | ||
|
|
c71307ed5c | ||
|
|
fa49dc980d | ||
|
|
206c0f38b4 | ||
|
|
19341bc544 | ||
|
|
c78198dc59 | ||
|
|
c63c8fbf90 | ||
|
|
6e84bab68c | ||
|
|
7f693a97ae | ||
|
|
4efe25d91d | ||
|
|
7262aead73 | ||
|
|
7153958e99 | ||
|
|
74ff522983 | ||
|
|
44635e752d | ||
|
|
d654ff2219 | ||
|
|
3e5d919b14 | ||
|
|
4e7caeb536 | ||
|
|
e25ab3cc8b | ||
|
|
299c7c670c | ||
|
|
fd4ac27d59 | ||
|
|
32d48cbc9d | ||
|
|
b01c6ecebd | ||
|
|
b645ce15cb | ||
|
|
2ffcbbd185 | ||
|
|
72ddb7eb08 | ||
|
|
25f6a934cf | ||
|
|
3f6c6d4447 | ||
|
|
608763a41a | ||
|
|
b27f3bacc0 | ||
|
|
27169b7c07 | ||
|
|
fe81322cc4 | ||
|
|
d433fe6956 | ||
|
|
e840ff7582 | ||
|
|
c9813a8c42 | ||
|
|
46a29037d4 | ||
|
|
d41b06dea2 | ||
|
|
71d31e60e6 | ||
|
|
02694d2a96 | ||
|
|
c88870b0a3 | ||
|
|
78305a7077 | ||
|
|
1ade196fb2 | ||
|
|
9b5bb8390c | ||
|
|
b88f66192f | ||
|
|
37c71cfe15 | ||
|
|
474487c33e | ||
|
|
a7c5507464 | ||
|
|
cdfb6d7ef1 | ||
|
|
5658b628b9 | ||
|
|
b429a00cce | ||
|
|
410ccce4a3 | ||
|
|
312a7a1e62 | ||
|
|
ed598e9fe1 | ||
|
|
fa97b0a95b | ||
|
|
3dfc79fb09 | ||
|
|
cc20e826e0 | ||
|
|
9742aeaf9b | ||
|
|
0d4aaa6def | ||
|
|
87794a3adb | ||
|
|
5fc5c03dad | ||
|
|
0d6de44a37 | ||
|
|
81f78f0da7 | ||
|
|
c38e0a4bbc | ||
|
|
1f0b317088 | ||
|
|
6c35d17800 | ||
|
|
df0983af39 | ||
|
|
fa81d838da | ||
|
|
45d62482da | ||
|
|
bcb41a09b3 | ||
|
|
9e2fbb31ec | ||
|
|
985504ff2c | ||
|
|
e304673c65 | ||
|
|
b8a102d26f | ||
|
|
d980d965dd | ||
|
|
f0239a8fe9 | ||
|
|
2e4503ad4e | ||
|
|
54ea8f74ae | ||
|
|
e647eeb0c9 | ||
|
|
26945d7956 | ||
|
|
c7851e0ee7 | ||
|
|
a011b67f56 | ||
|
|
c3f93e7178 | ||
|
|
931b1c6d59 | ||
|
|
e9d369a09e | ||
|
|
6adf561507 | ||
|
|
95adc0e6ba | ||
|
|
02753ba9ea | ||
|
|
acc1090e77 | ||
|
|
fc864529f5 | ||
|
|
782dd941da | ||
|
|
ba8290aeae | ||
|
|
4f6bc0a0a9 | ||
|
|
f7c8f1ae29 | ||
|
|
ba97ae1737 | ||
|
|
7669cfb330 | ||
|
|
bc0c9c7920 | ||
|
|
07c23ccc05 | ||
|
|
2130a07b70 | ||
|
|
26f899be10 | ||
|
|
bdb8bb790e | ||
|
|
8760f877e1 | ||
|
|
97882f9ce2 | ||
|
|
5fce21728e | ||
|
|
fa64b89ad7 | ||
|
|
49e9f93738 | ||
|
|
8028560f82 | ||
|
|
225a384dbb | ||
|
|
404379049a | ||
|
|
2a1bb91bf7 | ||
|
|
a33bb3e876 | ||
|
|
8cf1504ba6 | ||
|
|
427b820426 | ||
|
|
1d6bd50343 | ||
|
|
405cd82a82 | ||
|
|
64e14eaff5 | ||
|
|
ca29dc9abc | ||
|
|
dc42c35f1f | ||
|
|
b5b5221c13 | ||
|
|
995af0e2b7 | ||
|
|
5d21faa99c | ||
|
|
c9815307eb | ||
|
|
c1846177fc | ||
|
|
506adf3764 | ||
|
|
d551ab8e5c | ||
|
|
68d797587e | ||
|
|
6dc58ab6de | ||
|
|
a2520da195 | ||
|
|
3a73f17354 | ||
|
|
a397be388c | ||
|
|
ea9873e60e | ||
|
|
cfb78654c2 | ||
|
|
0a3bd83b19 | ||
|
|
924eb01299 | ||
|
|
81022ee8c7 | ||
|
|
a87d3af309 | ||
|
|
a60da0db1e | ||
|
|
051cf5437a | ||
|
|
311be04d61 | ||
|
|
aef7470418 | ||
|
|
2e0d82648f | ||
|
|
4c5522f7fa | ||
|
|
55e6a774a8 | ||
|
|
fc46660c96 | ||
|
|
058906c242 | ||
|
|
e61d3aa18f | ||
|
|
5e59c301b7 | ||
|
|
7e67db79dc | ||
|
|
f84d32ca5e | ||
|
|
5ee65eec5d | ||
|
|
d5bd2e40f0 | ||
|
|
66e4f554c3 | ||
|
|
a104b160b2 | ||
|
|
862182df4a | ||
|
|
5dd0e82809 | ||
|
|
2a1f27eb1a | ||
|
|
d721b42306 | ||
|
|
e15a8a7c46 | ||
|
|
49f07dca50 | ||
|
|
76ab267a35 | ||
|
|
75cb217c22 | ||
|
|
2680e4fa04 | ||
|
|
1b4ab580f3 | ||
|
|
42ac90ca49 | ||
|
|
c04755361c | ||
|
|
47340d3203 | ||
|
|
16e1b82cb8 | ||
|
|
834fbfed0a | ||
|
|
9b2778c439 | ||
|
|
f0d60cb1c8 | ||
|
|
1670d15e8a | ||
|
|
915b3a0255 | ||
|
|
ed65535c41 | ||
|
|
60cbdf9ccd | ||
|
|
5083e93957 | ||
|
|
f2ec911b8a | ||
|
|
c83d6ee0b1 | ||
|
|
83c96d2685 | ||
|
|
58b3d66229 | ||
|
|
bdbec099cc | ||
|
|
2ad9caad3f | ||
|
|
a337403868 | ||
|
|
e0cae08c04 | ||
|
|
99e9a4c786 | ||
|
|
7c94dae702 | ||
|
|
021c64310d | ||
|
|
8eb1a7d5dc | ||
|
|
f7a6482e6b | ||
|
|
909b737289 | ||
|
|
e5caf64815 | ||
|
|
ac9778395f | ||
|
|
1a33ea9671 | ||
|
|
9d88d82d5e | ||
|
|
6f417ec943 | ||
|
|
56d097cfe0 | ||
|
|
6ab17e3e15 | ||
|
|
12da13c9d1 | ||
|
|
d5999f8b5c | ||
|
|
bc6137f9e4 | ||
|
|
a585a1b81a | ||
|
|
a3129fd4e8 | ||
|
|
5caec3020d | ||
|
|
f4adcfa0e2 | ||
|
|
ecfeee2e82 | ||
|
|
899bee0056 | ||
|
|
00da99f2c4 | ||
|
|
72948d9f1d | ||
|
|
66d1193a00 | ||
|
|
fd47084224 | ||
|
|
d37a580085 | ||
|
|
50f8ead4e6 | ||
|
|
9f5aca62a9 | ||
|
|
9b7697db62 | ||
|
|
208e2dad1e | ||
|
|
ae5ddfdc1a | ||
|
|
ff599f4004 | ||
|
|
9d191a6093 | ||
|
|
4a4daf1303 | ||
|
|
92f187d1c2 | ||
|
|
845a664bb2 | ||
|
|
5ed17e84fa | ||
|
|
6a50cf89b4 | ||
|
|
39cf9c9d31 | ||
|
|
5a5db02b85 | ||
|
|
38cc1a1843 | ||
|
|
2a6b215328 | ||
|
|
88bc8f3528 | ||
|
|
f2be3ad46f | ||
|
|
2a3456cd3b | ||
|
|
bd5918760e | ||
|
|
4909a70174 | ||
|
|
d7e11d0af7 | ||
|
|
01831da5f5 | ||
|
|
af8134a6ff | ||
|
|
a988c36ccb | ||
|
|
e0f26dcda3 | ||
|
|
8f671d3eef | ||
|
|
3182728b70 | ||
|
|
5862f59ed7 | ||
|
|
1f94274b92 | ||
|
|
d2fb0efcd1 | ||
|
|
dbfce2a4d8 | ||
|
|
98994a8bb1 | ||
|
|
b580a55191 | ||
|
|
ff16836d1d | ||
|
|
5411033f66 | ||
|
|
8383409e88 | ||
|
|
d20a3ef57c | ||
|
|
bac8c72381 | ||
|
|
b9563340b7 | ||
|
|
8ae9329aa8 | ||
|
|
0417f1f2be | ||
|
|
4d5cab4085 | ||
|
|
3cdb2f0bb7 | ||
|
|
66bad2e979 | ||
|
|
7236838dea | ||
|
|
eb5ee80c74 | ||
|
|
a785a7f700 | ||
|
|
742976893e | ||
|
|
1d331c7e62 | ||
|
|
9fe8b28746 | ||
|
|
6a2ca34216 | ||
|
|
3b83bda29c | ||
|
|
a1bc339340 | ||
|
|
260de2cb5e | ||
|
|
890d8da2e3 | ||
|
|
ac8678aefe | ||
|
|
62d3af17f9 | ||
|
|
3ff46b2e43 | ||
|
|
dca93c56e0 | ||
|
|
73e30cbda8 | ||
|
|
c18fbefe93 | ||
|
|
c913fb99b6 | ||
|
|
8976dac9e0 | ||
|
|
bef217b241 | ||
|
|
1e2df2d464 | ||
|
|
9fd3318dd8 | ||
|
|
4e3015a892 | ||
|
|
bdbbd9711c | ||
|
|
9cccb8c115 | ||
|
|
4ec61bef46 | ||
|
|
0a2ef2b932 | ||
|
|
7b085136a7 | ||
|
|
534f9e3ab1 | ||
|
|
b32ce34cf2 | ||
|
|
3f47ff6ecd | ||
|
|
2adf3f42ee | ||
|
|
b642b3c8e3 | ||
|
|
d63de1e407 | ||
|
|
32e510bd70 | ||
|
|
28e72ae34d | ||
|
|
01a2ddf3f8 | ||
|
|
4fcc02ee9d | ||
|
|
78a00c845c | ||
|
|
2c482939fd | ||
|
|
933929cd62 | ||
|
|
40fefe2cbc | ||
|
|
fce56c56ef | ||
|
|
374e273df5 | ||
|
|
cf688db4b5 | ||
|
|
98967c5ec9 | ||
|
|
45b4e337cb | ||
|
|
82760a9960 | ||
|
|
c15487318b | ||
|
|
a58eaec540 | ||
|
|
7fe8edc396 | ||
|
|
8b4b3ff4fc | ||
|
|
577c0e3e5a | ||
|
|
5a5b950e8b | ||
|
|
f8a1f8843c | ||
|
|
9bba26f8c5 | ||
|
|
8fa822b521 | ||
|
|
64571368dc | ||
|
|
93742ed5df | ||
|
|
a77960c540 | ||
|
|
4b703d3049 | ||
|
|
ca5e6bf5f2 | ||
|
|
44cad8f4ed | ||
|
|
d0505fd042 | ||
|
|
349a62ed4f | ||
|
|
775fb562bd | ||
|
|
1686a15fb6 | ||
|
|
661d0dfac9 | ||
|
|
8213558cc7 | ||
|
|
a582b62287 | ||
|
|
bb820fa761 | ||
|
|
14d90e4901 | ||
|
|
3db0d50df4 | ||
|
|
f12d7f0d4b | ||
|
|
205d15e82d | ||
|
|
7b4b78b419 | ||
|
|
7b749eff35 | ||
|
|
f401791a56 | ||
|
|
dab63b029e | ||
|
|
64333e3ef8 | ||
|
|
c56b81a2ce | ||
|
|
23266e8e09 | ||
|
|
31d880f751 | ||
|
|
908e6bb68f | ||
|
|
276ca5f04c | ||
|
|
c4893d8efd | ||
|
|
1016f112bf | ||
|
|
b7397bf413 | ||
|
|
45a10dde95 | ||
|
|
88aa1c8dc3 | ||
|
|
e2917b2627 | ||
|
|
3df4959f51 | ||
|
|
531869bd92 | ||
|
|
c5689a5a40 | ||
|
|
a7027ed8e5 | ||
|
|
e71a915412 | ||
|
|
b2f19c9d06 | ||
|
|
f2d03f4fdd | ||
|
|
4f88344df3 | ||
|
|
a209ea3953 | ||
|
|
1da7475d0e | ||
|
|
d6daf37df4 | ||
|
|
5f483499f3 | ||
|
|
0cc812ae34 | ||
|
|
c41673f3fa | ||
|
|
1b86f520ea | ||
|
|
a0f3999ce7 | ||
|
|
69e0b8326a | ||
|
|
333da3b64b | ||
|
|
7062b0e65d | ||
|
|
f2e4aa8d1c | ||
|
|
00c34df186 | ||
|
|
35fd6d134a | ||
|
|
6f3475c6c7 | ||
|
|
005e462e01 | ||
|
|
dcdccf8333 | ||
|
|
e9b58d9de4 | ||
|
|
896581628d | ||
|
|
5577535891 | ||
|
|
696826913c | ||
|
|
455284f1c0 | ||
|
|
c975de2e07 | ||
|
|
ba7fb49fb9 | ||
|
|
b0a99e85b6 | ||
|
|
abb4e9e2fa | ||
|
|
17f6c3be8e | ||
|
|
01defc9f49 | ||
|
|
e8bb385d6d | ||
|
|
45f3cea263 | ||
|
|
a5e4d3a2d8 | ||
|
|
bf9c933cae | ||
|
|
da1f6fc2c8 | ||
|
|
44657bf932 | ||
|
|
67c3a014b9 | ||
|
|
07b0ea03c3 | ||
|
|
147b5ae514 | ||
|
|
9952201ca7 | ||
|
|
17c2c4219d | ||
|
|
3fc001d0a2 | ||
|
|
9c69a79f9a | ||
|
|
640c6fdd5f | ||
|
|
380a1ea8ef | ||
|
|
b85be36d1c | ||
|
|
54a3ed751e | ||
|
|
a22fe33aa0 | ||
|
|
e95df0bc39 | ||
|
|
c582f7d177 | ||
|
|
ca29903c82 | ||
|
|
e65306d8e7 | ||
|
|
c14fb5b633 | ||
|
|
ad437f13d5 | ||
|
|
4681415a15 | ||
|
|
7930cb54c0 | ||
|
|
91f53d590b | ||
|
|
3e0d31c4e9 | ||
|
|
4acc8d0ff5 | ||
|
|
3faa51a0ca | ||
|
|
3034a71488 | ||
|
|
2e2b8a95bd | ||
|
|
26a55ddcf9 | ||
|
|
1a4ddfa8a7 | ||
|
|
5383b047d1 | ||
|
|
14da999408 | ||
|
|
63a3fd3c0f | ||
|
|
8c39813665 | ||
|
|
3ebcf25149 | ||
|
|
a05c27a7e1 | ||
|
|
6bc3902f5d | ||
|
|
c2c2d44c72 | ||
|
|
515dfea4b7 | ||
|
|
31fd071faa | ||
|
|
0bfa615997 | ||
|
|
60ca29df64 | ||
|
|
35f582583a | ||
|
|
ddbc4a0f6c | ||
|
|
1f4a5b5dfe | ||
|
|
076034345a | ||
|
|
af2d48f4d2 | ||
|
|
8c8cddbe02 | ||
|
|
bbdc08780c | ||
|
|
174a2ad731 | ||
|
|
7c78b2b756 | ||
|
|
3be116bb6e | ||
|
|
e203bff96e | ||
|
|
a1c9d8784f | ||
|
|
2f43ed93b7 | ||
|
|
6e4adcc140 | ||
|
|
0783022d6d | ||
|
|
dfe63e9e73 | ||
|
|
2535b531bb | ||
|
|
92bf230b8a | ||
|
|
a37b7d1ae5 | ||
|
|
3ce7122aac | ||
|
|
ed4020b589 | ||
|
|
0d182e707e | ||
|
|
bb5634ce20 | ||
|
|
8a87170c8a | ||
|
|
604c43bfab | ||
|
|
246bec30bc | ||
|
|
aab28e3796 | ||
|
|
31326220fa | ||
|
|
089a594a68 | ||
|
|
13d3439933 | ||
|
|
b97568cac2 | ||
|
|
ebc4e5ecdf | ||
|
|
36bfa71b78 | ||
|
|
2e3661a0f6 | ||
|
|
7be65e79db | ||
|
|
c9a6e2560a | ||
|
|
59cab76dd8 | ||
|
|
ddf0a9dd55 | ||
|
|
edea6cf141 | ||
|
|
632553bdc9 | ||
|
|
7316ed33e1 | ||
|
|
8f19552af0 | ||
|
|
80f9e84b83 | ||
|
|
53355a0b92 | ||
|
|
16dd13979e | ||
|
|
12d681d8cc | ||
|
|
5d847fb0aa | ||
|
|
a50dcb09b5 | ||
|
|
edd194c23c | ||
|
|
fc4eaeb89f | ||
|
|
e52312ec3c | ||
|
|
844451c6ce | ||
|
|
a1d7bf7dc0 | ||
|
|
2dca2c0fd5 | ||
|
|
e70a5f8b7f | ||
|
|
a4e196366e | ||
|
|
69bc1bfde5 | ||
|
|
bf4edb4056 | ||
|
|
141428691e | ||
|
|
35daf6d805 | ||
|
|
839c4e3dd9 | ||
|
|
b7371802bf | ||
|
|
f89b98e1c3 | ||
|
|
6988b99fb4 | ||
|
|
56cee30ee8 | ||
|
|
7cdb1e2016 | ||
|
|
8131143fa8 | ||
|
|
a75e70f86b | ||
|
|
864124f4c0 | ||
|
|
05de59d106 | ||
|
|
0f7ccda4fb | ||
|
|
220b2afb3c |
183 changed files with 10363 additions and 5802 deletions
1
.github/FUNDING.yml
vendored
Normal file
1
.github/FUNDING.yml
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
github: nviennot
|
||||
41
.github/workflows/DragonflyBSD.yml
vendored
Normal file
41
.github/workflows/DragonflyBSD.yml
vendored
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
name: DragonflyBSD
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '*'
|
||||
paths:
|
||||
- '**.c'
|
||||
- '**.h'
|
||||
- 'compat/*'
|
||||
- '.github/workflows/DragonflyBSD.yml'
|
||||
pull_request:
|
||||
branches:
|
||||
- '*'
|
||||
paths:
|
||||
- '**.c'
|
||||
- '**.h'
|
||||
- 'compat/*'
|
||||
- '.github/workflows/DragonflyBSD.yml'
|
||||
|
||||
|
||||
|
||||
jobs:
|
||||
DragonflyBSD:
|
||||
runs-on: macos-12
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: vmactions/dragonflybsd-vm@v0
|
||||
with:
|
||||
prepare: |
|
||||
pkg install -y automake autoconf libtool pkgconf libevent msgpack libssh gsed
|
||||
usesh: true
|
||||
run: |
|
||||
gsed -i "s/OK/0/g" tty-term.c
|
||||
autoupdate
|
||||
./autogen.sh
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
|
||||
|
||||
|
||||
40
.github/workflows/FreeBSD.yml
vendored
Normal file
40
.github/workflows/FreeBSD.yml
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
name: FreeBSD
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '*'
|
||||
paths:
|
||||
- '**.c'
|
||||
- '**.h'
|
||||
- 'compat/*'
|
||||
- '.github/workflows/FreeBSD.yml'
|
||||
pull_request:
|
||||
branches:
|
||||
- '*'
|
||||
paths:
|
||||
- '**.c'
|
||||
- '**.h'
|
||||
- 'compat/*'
|
||||
- '.github/workflows/FreeBSD.yml'
|
||||
|
||||
|
||||
|
||||
jobs:
|
||||
FreeBSD:
|
||||
runs-on: macos-12
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: vmactions/freebsd-vm@v0
|
||||
with:
|
||||
prepare: |
|
||||
pkg install -y automake autoconf libtool pkgconf libevent msgpack libssh
|
||||
usesh: true
|
||||
run: |
|
||||
autoupdate
|
||||
./autogen.sh
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
|
||||
|
||||
|
||||
37
.github/workflows/MacOS.yml
vendored
Normal file
37
.github/workflows/MacOS.yml
vendored
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
name: MacOS
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '*'
|
||||
paths:
|
||||
- '**.c'
|
||||
- '**.h'
|
||||
- 'compat/*'
|
||||
- '.github/workflows/MacOS.yml'
|
||||
pull_request:
|
||||
branches:
|
||||
- '*'
|
||||
paths:
|
||||
- '**.c'
|
||||
- '**.h'
|
||||
- 'compat/*'
|
||||
- '.github/workflows/MacOS.yml'
|
||||
|
||||
|
||||
|
||||
jobs:
|
||||
MacOS:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: |
|
||||
brew install automake msgpack libssh
|
||||
autoupdate
|
||||
./autogen.sh
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
|
||||
|
||||
|
||||
|
||||
40
.github/workflows/NetBSD.yml
vendored
Normal file
40
.github/workflows/NetBSD.yml
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
name: NetBSD
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '*'
|
||||
paths:
|
||||
- '**.c'
|
||||
- '**.h'
|
||||
- 'compat/*'
|
||||
- '.github/workflows/NetBSD.yml'
|
||||
pull_request:
|
||||
branches:
|
||||
- '*'
|
||||
paths:
|
||||
- '**.c'
|
||||
- '**.h'
|
||||
- 'compat/*'
|
||||
- '.github/workflows/NetBSD.yml'
|
||||
|
||||
|
||||
|
||||
jobs:
|
||||
NetBSD:
|
||||
runs-on: macos-12
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: vmactions/netbsd-vm@v0
|
||||
with:
|
||||
prepare: |
|
||||
pkg_add automake autoconf libtool pkgconf libevent msgpack libssh
|
||||
usesh: true
|
||||
run: |
|
||||
autoupdate
|
||||
./autogen.sh
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
|
||||
|
||||
|
||||
50
.github/workflows/OpenBSD.yml
vendored
Normal file
50
.github/workflows/OpenBSD.yml
vendored
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
name: OpenBSD
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '*'
|
||||
paths:
|
||||
- '**.c'
|
||||
- '**.h'
|
||||
- 'compat/*'
|
||||
- '.github/workflows/OpenBSD.yml'
|
||||
pull_request:
|
||||
branches:
|
||||
- '*'
|
||||
paths:
|
||||
- '**.c'
|
||||
- '**.h'
|
||||
- 'compat/*'
|
||||
- '.github/workflows/OpenBSD.yml'
|
||||
|
||||
|
||||
|
||||
jobs:
|
||||
OpenBSD:
|
||||
runs-on: macos-12
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: vmactions/openbsd-vm@v0
|
||||
with:
|
||||
prepare: |
|
||||
pkg_add automake-1.16.3 autoconf-2.71 libtool pkgconf libevent msgpack libssh curl
|
||||
usesh: true
|
||||
run: |
|
||||
sed -i 's,<event.h>,<event2/event.h>,' *.[ch]
|
||||
curl https://raw.githubusercontent.com/openbsd/ports/master/sysutils/tmate/patches/patch-Makefile_am | patch
|
||||
curl https://raw.githubusercontent.com/openbsd/ports/master/sysutils/tmate/patches/patch-server_c | patch
|
||||
curl https://raw.githubusercontent.com/openbsd/ports/master/sysutils/tmate/patches/patch-tmate-debug_c | patch
|
||||
curl https://raw.githubusercontent.com/openbsd/ports/master/sysutils/tmate/patches/patch-tmate_h | patch
|
||||
curl https://raw.githubusercontent.com/openbsd/ports/master/sysutils/tmate/patches/patch-tmux_c | patch
|
||||
curl https://raw.githubusercontent.com/openbsd/ports/master/sysutils/tmate/patches/patch-tmux_h | patch
|
||||
curl https://raw.githubusercontent.com/openbsd/ports/master/sysutils/tmate/patches/patch-osdep-openbsd_c | patch
|
||||
export AUTOMAKE_VERSION=1.16
|
||||
export AUTOCONF_VERSION=2.71
|
||||
autoupdate
|
||||
./autogen.sh
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
|
||||
|
||||
|
||||
37
.github/workflows/Ubuntu.yml
vendored
Normal file
37
.github/workflows/Ubuntu.yml
vendored
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
name: Ubuntu
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '*'
|
||||
paths:
|
||||
- '**.c'
|
||||
- '**.h'
|
||||
- 'compat/*'
|
||||
- '.github/workflows/Ubuntu.yml'
|
||||
pull_request:
|
||||
branches:
|
||||
- '*'
|
||||
paths:
|
||||
- '**.c'
|
||||
- '**.h'
|
||||
- 'compat/*'
|
||||
- '.github/workflows/Ubuntu.yml'
|
||||
|
||||
|
||||
|
||||
jobs:
|
||||
Ubuntu:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- run: |
|
||||
sudo apt-get install -y build-essential automake libtool libevent-dev libncurses5-dev libmsgpack-dev libssh-dev pkg-config
|
||||
autoupdate
|
||||
ACLOCAL_PATH=/usr/share/aclocal ./autogen.sh
|
||||
./configure
|
||||
make
|
||||
sudo make install
|
||||
|
||||
|
||||
|
||||
|
||||
11
.gitignore
vendored
11
.gitignore
vendored
|
|
@ -16,4 +16,13 @@ tmux
|
|||
Makefile
|
||||
Makefile.in
|
||||
configure
|
||||
tmux.1.*
|
||||
tmate
|
||||
cscope.*
|
||||
ctags
|
||||
*.log
|
||||
tmate.1.*
|
||||
downloads/
|
||||
ext/
|
||||
libssh-*/
|
||||
msgpack-*/
|
||||
releases/
|
||||
|
|
|
|||
8
.mailmap
8
.mailmap
|
|
@ -1,9 +1,9 @@
|
|||
Bob Beck <beck@openbsd.org> beck <beck>
|
||||
Claudio Jeker <claudio@openbsd.org> claudio <claudio>
|
||||
Igor Sobrado <sobrado@openbsd.org> sobrado <sobrado>
|
||||
Ingo Schwarze <schwarze@openbsd.org> schwarze <schwarze>
|
||||
Jacek Masiulaniec <jacekm@openbsd.org> jacekm <jacekm>
|
||||
Jason McIntyre <jmc@openbsd.org> jmc <jmc>
|
||||
Jason McIntyre <jmc@openbsd.org> jcm <jcm>
|
||||
Joel Sing <jsing@openbsd.org> jsing <jsing>
|
||||
Jonathan Gray <jsg@openbsd.org> jsg <jsg>
|
||||
Kenneth R Westerback <krw@openbsd.org> krw <krw>
|
||||
|
|
@ -11,6 +11,7 @@ Marc Espie <espie@openbsd.org> espie <espie>
|
|||
Matthew Dempsky <matthew@openbsd.org> matthew <matthew>
|
||||
Matthias Kilian <kili@openbsd.org> kili <kili>
|
||||
Matthieu Herrb <matthieu@openbsd.org> matthieu <matthieu>
|
||||
Michael McConville <mmcc@openbsd.org> mmcc <mmcc>
|
||||
Miod Vallat <miod@openbsd.org> miod <miod>
|
||||
Nicholas Marriott <nicholas.marriott@gmail.com> Nicholas Marriott <nicm@openbsd.org>
|
||||
Nicholas Marriott <nicholas.marriott@gmail.com> nicm <nicm>
|
||||
|
|
@ -24,11 +25,12 @@ Sebastian Benoit <benno@openbsd.org> benno <benno>
|
|||
Stefan Sperling <stsp@openbsd.org> stsp <stsp>
|
||||
Stuart Henderson <sthen@openbsd.org> sthen <sthen>
|
||||
Ted Unangst <tedu@openbsd.org> tedu <tedu>
|
||||
Theo de Raadt <deraadt@openbsd.org> deraadt <deraadt>
|
||||
Theo de Raadt <deraadt@openbsd.org> Theo Deraadt <deraadt@openbsd.org>
|
||||
Theo de Raadt <deraadt@openbsd.org> deraadt <deraadt>
|
||||
Thomas Adam <thomas@xteddy.org> Thomas <thomas@xteddy.org>
|
||||
Thomas Adam <thomas@xteddy.org> n6tadam <n6tadam@xteddy.org>
|
||||
Thomas Adam <thomas@xteddy.org> Thomas Adam <thomas.adam@smoothwall.net>
|
||||
Thomas Adam <thomas@xteddy.org> n6tadam <n6tadam@xteddy.org>
|
||||
Tim van der Molen <tim@openbsd.org> tim <tim>
|
||||
Tobias Stoeckmann <tobias@openbsd.org> tobias <tobias>
|
||||
Todd C Miller <millert@openbsd.org> millert <millert>
|
||||
William Yodlowsky <william@openbsd.org> william <william>
|
||||
|
|
|
|||
46
.travis.yml
46
.travis.yml
|
|
@ -1,10 +1,40 @@
|
|||
language: c
|
||||
services:
|
||||
- docker
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- compiler: gcc
|
||||
- compiler: clang
|
||||
env: CFLAGS="-g -O2"
|
||||
before_install:
|
||||
- sudo apt-get update -qq
|
||||
- sudo apt-get -y install debhelper autotools-dev dh-autoreconf file libncurses5-dev libevent-dev pkg-config libutempter-dev build-essential
|
||||
script: (CFLAGS= ./autogen.sh) && ./configure --enable-debug && make
|
||||
include:
|
||||
- arch: amd64
|
||||
env: PLATFORM=amd64
|
||||
- arch: amd64
|
||||
env: PLATFORM=i386
|
||||
- arch: arm64
|
||||
env: PLATFORM=arm32v6
|
||||
- arch: arm64
|
||||
env: PLATFORM=arm32v7
|
||||
- arch: arm64
|
||||
env: PLATFORM=arm64v8
|
||||
- arch: s390x
|
||||
env: PLATFORM=s390x
|
||||
- arch: ppc64le
|
||||
env: PLATFORM=ppc64le
|
||||
|
||||
script:
|
||||
- 'docker build . --tag local-$PLATFORM/tmate-build --build-arg PLATFORM=$PLATFORM'
|
||||
# On arch=arm64, some directories are not setup correctly, and 'ruby -S gem
|
||||
# install dpl' required by the release push scripts fails.
|
||||
- 'if [ "$TRAVIS_TAG" ]; then sudo chown -R $USER: /var/lib/gems /usr/local/bin; fi'
|
||||
- 'if [ "$TRAVIS_TAG" ]; then ./build_static_release.sh $TRAVIS_TAG $PLATFORM; fi'
|
||||
|
||||
deploy:
|
||||
provider: releases
|
||||
api_key:
|
||||
secure: T2109tjjOsrVLEpJZK/uxmO0AuDGXYFdN4AAsNTmVwu/W5dcX57Kk2TCgqDuLfD21iGGXP0U/OYHM06IfBDODBWCA9P8ASHYsenS7wIiFnvCEMbfzoAFyBMrXN2kNdM2+ho3aqc0xE2lQKOKDLxpGm5FZrzujscXXzxQjWBU5Hk=
|
||||
skip_cleanup: true
|
||||
overwrite: true
|
||||
file_glob: true
|
||||
file: releases/*.tar.*
|
||||
on:
|
||||
repo: tmate-io/tmate
|
||||
branch: master
|
||||
tags: true
|
||||
|
|
|
|||
37
Dockerfile
Normal file
37
Dockerfile
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
ARG PLATFORM=amd64
|
||||
FROM ${PLATFORM}/alpine:3.10 AS build
|
||||
|
||||
WORKDIR /build
|
||||
|
||||
RUN apk add --no-cache wget cmake make gcc g++ linux-headers zlib-dev openssl-dev \
|
||||
automake autoconf libevent-dev ncurses-dev msgpack-c-dev libexecinfo-dev \
|
||||
ncurses-static libexecinfo-static libevent-static msgpack-c ncurses-libs \
|
||||
libevent libexecinfo openssl zlib
|
||||
|
||||
RUN set -ex; \
|
||||
mkdir -p /src/libssh/build; \
|
||||
cd /src; \
|
||||
wget -O libssh.tar.xz https://www.libssh.org/files/0.9/libssh-0.9.0.tar.xz; \
|
||||
tar -xf libssh.tar.xz -C /src/libssh --strip-components=1; \
|
||||
cd /src/libssh/build; \
|
||||
cmake -DCMAKE_INSTALL_PREFIX:PATH=/usr \
|
||||
-DWITH_SFTP=OFF -DWITH_SERVER=OFF -DWITH_PCAP=OFF \
|
||||
-DWITH_STATIC_LIB=ON -DWITH_GSSAPI=OFF ..; \
|
||||
make -j $(nproc); \
|
||||
make install
|
||||
|
||||
COPY compat ./compat
|
||||
COPY *.c *.h autogen.sh Makefile.am configure.ac ./
|
||||
|
||||
RUN ./autogen.sh && ./configure --enable-static
|
||||
RUN make -j $(nproc)
|
||||
RUN objcopy --only-keep-debug tmate tmate.symbols && chmod -x tmate.symbols && strip tmate
|
||||
RUN ./tmate -V
|
||||
|
||||
FROM alpine:3.9
|
||||
|
||||
RUN apk --no-cache add bash
|
||||
RUN mkdir /build
|
||||
ENV PATH=/build:$PATH
|
||||
COPY --from=build /build/tmate.symbols /build
|
||||
COPY --from=build /build/tmate /build
|
||||
90
Makefile.am
90
Makefile.am
|
|
@ -1,13 +1,13 @@
|
|||
# Makefile.am
|
||||
|
||||
# Obvious program stuff.
|
||||
bin_PROGRAMS = tmux
|
||||
CLEANFILES = tmux.1.mdoc tmux.1.man
|
||||
bin_PROGRAMS = tmate
|
||||
CLEANFILES = tmate.1.mdoc tmate.1.man
|
||||
|
||||
# Distribution tarball options.
|
||||
EXTRA_DIST = \
|
||||
CHANGES FAQ README TODO COPYING examples compat/*.[ch] \
|
||||
array.h compat.h tmux.h osdep-*.c mdoc2man.awk tmux.1
|
||||
CHANGES FAQ README TODO COPYING example_tmux.conf compat/*.[ch] \
|
||||
array.h compat.h tmux.h osdep-*.c xmalloc.h mdoc2man.awk tmate.1
|
||||
dist-hook:
|
||||
make clean
|
||||
grep "^#found_debug=" configure
|
||||
|
|
@ -21,6 +21,10 @@ if IS_GLIBC
|
|||
CFLAGS += -D_GNU_SOURCE
|
||||
endif
|
||||
|
||||
if IS_LINUX
|
||||
CFLAGS += -rdynamic # for stack traces
|
||||
endif
|
||||
|
||||
# Set flags for gcc.
|
||||
if IS_GCC
|
||||
CFLAGS += -std=gnu99 -O2
|
||||
|
|
@ -29,8 +33,8 @@ CFLAGS += -g
|
|||
CFLAGS += -Wno-long-long -Wall -W -Wnested-externs -Wformat=2
|
||||
CFLAGS += -Wmissing-prototypes -Wstrict-prototypes -Wmissing-declarations
|
||||
CFLAGS += -Wwrite-strings -Wshadow -Wpointer-arith -Wsign-compare
|
||||
CFLAGS += -Wundef -Wbad-function-cast -Winline -Wcast-align
|
||||
CFLAGS += -Wdeclaration-after-statement -Wno-pointer-sign
|
||||
CFLAGS += -Wundef -Wbad-function-cast -Winline
|
||||
CFLAGS += -Wno-pointer-sign -Wno-attributes
|
||||
CPPFLAGS += -DDEBUG
|
||||
endif
|
||||
if IS_COVERAGE
|
||||
|
|
@ -40,6 +44,9 @@ endif
|
|||
CPPFLAGS += -iquote.
|
||||
endif
|
||||
|
||||
CFLAGS += -Wno-unused-parameter -Wno-unused-variable -Wno-null-pointer-arithmetic
|
||||
CFLAGS += -Wno-deprecated-declarations -Wno-format-nonliteral
|
||||
|
||||
# Set flags for Solaris.
|
||||
if IS_SUNOS
|
||||
if IS_GCC
|
||||
|
|
@ -54,13 +61,13 @@ if IS_SUNCC
|
|||
CFLAGS += -erroff=E_EMPTY_DECLARATION
|
||||
endif
|
||||
|
||||
# Set _LINUX_SOURCE_COMPAT for AIX for mallocing 0 bytes
|
||||
# Set _LINUX_SOURCE_COMPAT for AIX for malloc(0).
|
||||
if IS_AIX
|
||||
DEFS += -D_LINUX_SOURCE_COMPAT=1
|
||||
endif
|
||||
|
||||
# List of sources.
|
||||
dist_tmux_SOURCES = \
|
||||
dist_tmate_SOURCES = \
|
||||
alerts.c \
|
||||
arguments.c \
|
||||
attributes.c \
|
||||
|
|
@ -118,6 +125,7 @@ dist_tmux_SOURCES = \
|
|||
cmd-send-keys.c \
|
||||
cmd-set-buffer.c \
|
||||
cmd-set-environment.c \
|
||||
cmd-set-hook.c \
|
||||
cmd-set-option.c \
|
||||
cmd-show-environment.c \
|
||||
cmd-show-messages.c \
|
||||
|
|
@ -136,9 +144,9 @@ dist_tmux_SOURCES = \
|
|||
control-notify.c \
|
||||
environ.c \
|
||||
format.c \
|
||||
grid-cell.c \
|
||||
grid-view.c \
|
||||
grid.c \
|
||||
hooks.c \
|
||||
input-keys.c \
|
||||
input.c \
|
||||
job.c \
|
||||
|
|
@ -154,6 +162,7 @@ dist_tmux_SOURCES = \
|
|||
options-table.c \
|
||||
options.c \
|
||||
paste.c \
|
||||
proc.c \
|
||||
resize.c \
|
||||
screen-redraw.c \
|
||||
screen-write.c \
|
||||
|
|
@ -165,6 +174,14 @@ dist_tmux_SOURCES = \
|
|||
signal.c \
|
||||
status.c \
|
||||
style.c \
|
||||
tmate-debug.c \
|
||||
tmate-ssh-client.c \
|
||||
tmate-encoder.c \
|
||||
tmate-decoder.c \
|
||||
tmate-env.c \
|
||||
tmate-msg.c \
|
||||
tmate-msgpack.c \
|
||||
tmate-session.c \
|
||||
tmux.c \
|
||||
tty-acs.c \
|
||||
tty-keys.c \
|
||||
|
|
@ -177,73 +194,76 @@ dist_tmux_SOURCES = \
|
|||
window.c \
|
||||
xmalloc.c \
|
||||
xterm-keys.c
|
||||
nodist_tmux_SOURCES = osdep-@PLATFORM@.c
|
||||
nodist_tmate_SOURCES = osdep-@PLATFORM@.c
|
||||
|
||||
# Pile in all the compat/ stuff that is needed.
|
||||
if NO_FORKPTY
|
||||
nodist_tmux_SOURCES += compat/forkpty-@PLATFORM@.c
|
||||
nodist_tmate_SOURCES += compat/forkpty-@PLATFORM@.c
|
||||
endif
|
||||
if NO_IMSG
|
||||
nodist_tmux_SOURCES += compat/imsg.c compat/imsg-buffer.c
|
||||
nodist_tmate_SOURCES += compat/imsg.c compat/imsg-buffer.c
|
||||
endif
|
||||
if NO_CLOSEFROM
|
||||
nodist_tmux_SOURCES += compat/closefrom.c
|
||||
nodist_tmate_SOURCES += compat/closefrom.c
|
||||
endif
|
||||
if NO_DAEMON
|
||||
nodist_tmux_SOURCES += compat/daemon.c
|
||||
nodist_tmate_SOURCES += compat/daemon.c
|
||||
endif
|
||||
if NO_SETENV
|
||||
nodist_tmux_SOURCES += compat/setenv.c
|
||||
nodist_tmate_SOURCES += compat/setenv.c
|
||||
endif
|
||||
if NO_STRLCAT
|
||||
nodist_tmux_SOURCES += compat/strlcat.c
|
||||
nodist_tmate_SOURCES += compat/strlcat.c
|
||||
endif
|
||||
if NO_STRLCPY
|
||||
nodist_tmux_SOURCES += compat/strlcpy.c
|
||||
nodist_tmate_SOURCES += compat/strlcpy.c
|
||||
endif
|
||||
if NO_ASPRINTF
|
||||
nodist_tmux_SOURCES += compat/asprintf.c
|
||||
nodist_tmate_SOURCES += compat/asprintf.c
|
||||
endif
|
||||
if NO_FGETLN
|
||||
nodist_tmux_SOURCES += compat/fgetln.c
|
||||
nodist_tmate_SOURCES += compat/fgetln.c
|
||||
endif
|
||||
if NO_FPARSELN
|
||||
nodist_tmux_SOURCES += compat/fparseln.c
|
||||
nodist_tmate_SOURCES += compat/fparseln.c
|
||||
endif
|
||||
if NO_GETOPT
|
||||
nodist_tmux_SOURCES += compat/getopt.c
|
||||
nodist_tmate_SOURCES += compat/getopt.c
|
||||
endif
|
||||
if NO_STRCASESTR
|
||||
nodist_tmux_SOURCES += compat/strcasestr.c
|
||||
nodist_tmate_SOURCES += compat/strcasestr.c
|
||||
endif
|
||||
if NO_STRSEP
|
||||
nodist_tmux_SOURCES += compat/strsep.c
|
||||
nodist_tmate_SOURCES += compat/strsep.c
|
||||
endif
|
||||
if NO_VIS
|
||||
nodist_tmux_SOURCES += compat/vis.c compat/unvis.c
|
||||
nodist_tmate_SOURCES += compat/vis.c compat/unvis.c
|
||||
endif
|
||||
if NO_STRTONUM
|
||||
nodist_tmux_SOURCES += compat/strtonum.c
|
||||
nodist_tmate_SOURCES += compat/strtonum.c
|
||||
endif
|
||||
if NO_B64_NTOP
|
||||
nodist_tmux_SOURCES += compat/b64_ntop.c
|
||||
nodist_tmate_SOURCES += compat/b64_ntop.c
|
||||
endif
|
||||
if NO_CFMAKERAW
|
||||
nodist_tmux_SOURCES += compat/cfmakeraw.c
|
||||
nodist_tmate_SOURCES += compat/cfmakeraw.c
|
||||
endif
|
||||
if NO_OPENAT
|
||||
nodist_tmux_SOURCES += compat/openat.c
|
||||
nodist_tmate_SOURCES += compat/openat.c
|
||||
endif
|
||||
if NO_REALLOCARRAY
|
||||
nodist_tmate_SOURCES += compat/reallocarray.c
|
||||
endif
|
||||
|
||||
# Install tmux.1 in the right format.
|
||||
# Install tmate.1 in the right format.
|
||||
install-exec-hook:
|
||||
if test x@MANFORMAT@ = xmdoc; then \
|
||||
sed -e "s|@SYSCONFDIR@|$(sysconfdir)|g" $(srcdir)/tmux.1 \
|
||||
>$(srcdir)/tmux.1.mdoc; \
|
||||
sed -e "s|@SYSCONFDIR@|$(sysconfdir)|g" $(srcdir)/tmate.1 \
|
||||
>$(srcdir)/tmate.1.mdoc; \
|
||||
else \
|
||||
sed -e "s|@SYSCONFDIR@|$(sysconfdir)|g" $(srcdir)/tmux.1| \
|
||||
$(AWK) -f$(srcdir)/mdoc2man.awk >$(srcdir)/tmux.1.man; \
|
||||
sed -e "s|@SYSCONFDIR@|$(sysconfdir)|g" $(srcdir)/tmate.1| \
|
||||
$(AWK) -f$(srcdir)/mdoc2man.awk >$(srcdir)/tmate.1.man; \
|
||||
fi
|
||||
$(mkdir_p) $(DESTDIR)$(mandir)/man1
|
||||
$(INSTALL_DATA) $(srcdir)/tmux.1.@MANFORMAT@ \
|
||||
$(DESTDIR)$(mandir)/man1/tmux.1
|
||||
$(INSTALL_DATA) $(srcdir)/tmate.1.@MANFORMAT@ \
|
||||
$(DESTDIR)$(mandir)/man1/tmate.1
|
||||
|
|
|
|||
21
README
21
README
|
|
@ -8,7 +8,7 @@ This release runs on OpenBSD, FreeBSD, NetBSD, Linux, OS X and Solaris.
|
|||
|
||||
tmux depends on libevent 2.x. Download it from:
|
||||
|
||||
http://www.monkey.org/~provos/libevent/
|
||||
http://libevent.org
|
||||
|
||||
To build tmux from a release tarball, do:
|
||||
|
||||
|
|
@ -33,8 +33,16 @@ the source tree with:
|
|||
Some common questions are answered in the FAQ file and a more extensive (but
|
||||
slightly out of date) guide is available in the OpenBSD FAQ at
|
||||
http://www.openbsd.org/faq/faq7.html#tmux. A rough todo list is in the TODO
|
||||
file and some example configurations and a Vim syntax file are in the examples
|
||||
directory.
|
||||
file and an example configuration in example_tmux.conf.
|
||||
|
||||
A vim(1) syntax file is available at:
|
||||
|
||||
https://github.com/keith/tmux.vim
|
||||
https://raw.githubusercontent.com/keith/tmux.vim/master/syntax/tmux.vim
|
||||
|
||||
And a bash(1) completion file at:
|
||||
|
||||
https://github.com/przepompownia/tmux-bash-completion
|
||||
|
||||
For debugging, running tmux with -v or -vv will generate server and client log
|
||||
files in the current directory.
|
||||
|
|
@ -52,10 +60,7 @@ welcome. Please send by email to:
|
|||
|
||||
tmux-users@googlegroups.com
|
||||
|
||||
This file and the CHANGES, FAQ, SYNCING and TODO files are licensed under
|
||||
the ISC license. Files under examples/ remain copyright their authors unless
|
||||
otherwise stated in the file but permission has been received to distribute
|
||||
them with tmux. All other files have a license and copyright notice at their
|
||||
start.
|
||||
This file and the CHANGES, FAQ, SYNCING and TODO files are licensed under the
|
||||
ISC license. All other files have a license and copyright notice at their start.
|
||||
|
||||
-- Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
|
|
|
|||
61
README-tmux
Normal file
61
README-tmux
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
Welcome to tmux!
|
||||
|
||||
tmux is a "terminal multiplexer", it enables a number of terminals (or windows)
|
||||
to be accessed and controlled from a single terminal. tmux is intended to be a
|
||||
simple, modern, BSD-licensed alternative to programs such as GNU screen.
|
||||
|
||||
This release runs on OpenBSD, FreeBSD, NetBSD, Linux, OS X and Solaris.
|
||||
|
||||
tmux depends on libevent 2.x. Download it from:
|
||||
|
||||
http://www.monkey.org/~provos/libevent/
|
||||
|
||||
To build tmux from a release tarball, do:
|
||||
|
||||
$ ./configure && make
|
||||
$ sudo make install
|
||||
|
||||
To get and build the latest from version control:
|
||||
|
||||
$ git clone https://github.com/tmux/tmux.git
|
||||
$ cd tmux
|
||||
$ sh autogen.sh
|
||||
$ ./configure && make
|
||||
|
||||
For more information see http://git-scm.com. Patches should be sent by email to
|
||||
the mailing list at tmux-users@googlegroups.com.
|
||||
|
||||
For documentation on using tmux, see the tmux.1 manpage. It can be viewed from
|
||||
the source tree with:
|
||||
|
||||
$ nroff -mdoc tmux.1|less
|
||||
|
||||
Some common questions are answered in the FAQ file and a more extensive (but
|
||||
slightly out of date) guide is available in the OpenBSD FAQ at
|
||||
http://www.openbsd.org/faq/faq7.html#tmux. A rough todo list is in the TODO
|
||||
file and some example configurations and a Vim syntax file are in the examples
|
||||
directory.
|
||||
|
||||
For debugging, running tmux with -v or -vv will generate server and client log
|
||||
files in the current directory.
|
||||
|
||||
tmux mailing lists are available. For general discussion and bug reports:
|
||||
|
||||
https://groups.google.com/forum/#!forum/tmux-users
|
||||
|
||||
And for Git commit emails:
|
||||
|
||||
https://groups.google.com/forum/#!forum/tmux-git
|
||||
|
||||
Bug reports, feature suggestions and especially code contributions are most
|
||||
welcome. Please send by email to:
|
||||
|
||||
tmux-users@googlegroups.com
|
||||
|
||||
This file and the CHANGES, FAQ, SYNCING and TODO files are licensed under
|
||||
the ISC license. Files under examples/ remain copyright their authors unless
|
||||
otherwise stated in the file but permission has been received to distribute
|
||||
them with tmux. All other files have a license and copyright notice at their
|
||||
start.
|
||||
|
||||
-- Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
12
README.md
Normal file
12
README.md
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
tmate
|
||||
=====
|
||||
|
||||
What is it?
|
||||
-----------
|
||||
|
||||
Tmate is a fork of tmux. It provides an instant pairing solution.
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
tmate is built on top of tmux. tmux and tmate are BSD-licensed.
|
||||
23
TODO
23
TODO
|
|
@ -5,6 +5,8 @@
|
|||
* ' and " should be parsed the same (eg "\e" vs '\e') in config
|
||||
and command prompt
|
||||
* last-pane across sessions
|
||||
* list-keys should quote output so that bindings can just be used in
|
||||
config file as-is
|
||||
|
||||
- make command sequences more usable
|
||||
* don't require space after ;
|
||||
|
|
@ -15,10 +17,9 @@
|
|||
* way to set socket path from config file
|
||||
|
||||
- format improvements:
|
||||
* option to quote format (#{session_name:quoted})
|
||||
* option to quote format (#{q:session_name})
|
||||
* formats need conditions for >0 (for #P)
|
||||
* some way to pad # stuff with spaces
|
||||
* last window update time and format for it
|
||||
* formats to show if a window is linked into multiple sessions, into
|
||||
multiple attached sessions, and is the active window in multiple
|
||||
attached sessions?
|
||||
|
|
@ -51,10 +52,8 @@
|
|||
* split-window -> split-pane?
|
||||
|
||||
- better UTF-8 support:
|
||||
* window names and titles
|
||||
* message display
|
||||
* prompt input
|
||||
* multibyte key input
|
||||
* searching in copy mode
|
||||
|
||||
- copy/paste improvements:
|
||||
|
|
@ -63,6 +62,20 @@
|
|||
* command to toggle selection not to move it in copy-mode
|
||||
* regex searching
|
||||
* copy-pipe should have -x as well
|
||||
* copy mode key bindings should just be a standard key table, using
|
||||
something like "copy-mode start-selection"; it could use
|
||||
command-prompt for search, goto, etc:
|
||||
|
||||
bind -Temacs command-prompt -p'Search Up: ' 'copy-mode search-up %%'
|
||||
|
||||
it'd need a separate lookup, because modes are per-pane, perhaps a
|
||||
table() cb to give the table name ("vi" or "emacs"). anything in the
|
||||
table fires the command, anything not in the table is injected as a
|
||||
key
|
||||
* searching in copy mode should unwrap lines, so if you seach for "foobar"
|
||||
then it should be found even if it is now "foo\nbar" (if the WRAP flag
|
||||
is set on the line)
|
||||
* {} to go to next/previous blank line in copy mode
|
||||
|
||||
- layout stuff
|
||||
* way to tag a layout as a number/name
|
||||
|
|
@ -119,7 +132,7 @@
|
|||
comes from config for new sessions and windows. likewise, panes and
|
||||
jobs and run-shell and lock command all start with slightly different
|
||||
environments
|
||||
* multiline status line?
|
||||
* multiline status line? separate command prompt and status line?
|
||||
* customizable command aliases
|
||||
* automatic pane logging
|
||||
* BCE? We are halfway there (output side is done for pane backgrounds),
|
||||
|
|
|
|||
117
alerts.c
117
alerts.c
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2015 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2015 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -29,13 +29,15 @@ int alerts_enabled(struct window *, int);
|
|||
void alerts_callback(int, short, void *);
|
||||
void alerts_reset(struct window *);
|
||||
|
||||
void alerts_run_hook(struct session *, struct winlink *, int);
|
||||
int alerts_check_all(struct session *, struct winlink *);
|
||||
int alerts_check_bell(struct session *, struct winlink *);
|
||||
int alerts_check_activity(struct session *, struct winlink *);
|
||||
int alerts_check_silence(struct session *, struct winlink *);
|
||||
void alerts_ring_bell(struct session *);
|
||||
|
||||
void
|
||||
alerts_timer(unused int fd, unused short events, void *arg)
|
||||
alerts_timer(__unused int fd, __unused short events, void *arg)
|
||||
{
|
||||
struct window *w = arg;
|
||||
|
||||
|
|
@ -45,7 +47,7 @@ alerts_timer(unused int fd, unused short events, void *arg)
|
|||
}
|
||||
|
||||
void
|
||||
alerts_callback(unused int fd, unused short events, unused void *arg)
|
||||
alerts_callback(__unused int fd, __unused short events, __unused void *arg)
|
||||
{
|
||||
struct window *w;
|
||||
struct session *s;
|
||||
|
|
@ -59,11 +61,7 @@ alerts_callback(unused int fd, unused short events, unused void *arg)
|
|||
continue;
|
||||
flags = w->flags;
|
||||
|
||||
alerts = alerts_check_bell(s, wl);
|
||||
alerts |= alerts_check_activity(s, wl);
|
||||
alerts |= alerts_check_silence(s, wl);
|
||||
if (alerts != 0)
|
||||
server_status_session(s);
|
||||
alerts = alerts_check_all(s, wl);
|
||||
|
||||
log_debug("%s:%d @%u alerts check, alerts %#x, "
|
||||
"flags %#x", s->name, wl->idx, w->id,
|
||||
|
|
@ -74,25 +72,58 @@ alerts_callback(unused int fd, unused short events, unused void *arg)
|
|||
alerts_fired = 0;
|
||||
}
|
||||
|
||||
void
|
||||
alerts_run_hook(struct session *s, struct winlink *wl, int flags)
|
||||
{
|
||||
struct cmd_find_state fs;
|
||||
|
||||
if (cmd_find_from_winlink(&fs, s, wl) != 0)
|
||||
return;
|
||||
|
||||
if (flags & WINDOW_BELL)
|
||||
hooks_run(s->hooks, NULL, &fs, "alert-bell");
|
||||
if (flags & WINDOW_SILENCE)
|
||||
hooks_run(s->hooks, NULL, &fs, "alert-silence");
|
||||
if (flags & WINDOW_ACTIVITY)
|
||||
hooks_run(s->hooks, NULL, &fs, "alert-activity");
|
||||
}
|
||||
|
||||
int
|
||||
alerts_check_all(struct session *s, struct winlink *wl)
|
||||
{
|
||||
int alerts;
|
||||
|
||||
alerts = alerts_check_bell(s, wl);
|
||||
alerts |= alerts_check_activity(s, wl);
|
||||
alerts |= alerts_check_silence(s, wl);
|
||||
if (alerts != 0) {
|
||||
alerts_run_hook(s, wl, alerts);
|
||||
server_status_session(s);
|
||||
}
|
||||
|
||||
return (alerts);
|
||||
}
|
||||
|
||||
void
|
||||
alerts_check_session(struct session *s)
|
||||
{
|
||||
struct winlink *wl;
|
||||
|
||||
RB_FOREACH(wl, winlinks, &s->windows)
|
||||
alerts_check_all(s, wl);
|
||||
}
|
||||
|
||||
int
|
||||
alerts_enabled(struct window *w, int flags)
|
||||
{
|
||||
struct session *s;
|
||||
|
||||
if (flags & WINDOW_BELL)
|
||||
return (1);
|
||||
if (flags & WINDOW_ACTIVITY) {
|
||||
if (options_get_number(&w->options, "monitor-activity"))
|
||||
if (options_get_number(w->options, "monitor-activity"))
|
||||
return (1);
|
||||
}
|
||||
if (flags & WINDOW_SILENCE) {
|
||||
if (options_get_number(&w->options, "monitor-silence") != 0)
|
||||
return (1);
|
||||
}
|
||||
if (~flags & WINDOW_BELL)
|
||||
return (0);
|
||||
RB_FOREACH(s, sessions, &sessions) {
|
||||
if (!session_has(s, w))
|
||||
continue;
|
||||
if (options_get_number(&s->options, "bell-action") != BELL_NONE)
|
||||
if (options_get_number(w->options, "monitor-silence") != 0)
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
|
|
@ -116,7 +147,7 @@ alerts_reset(struct window *w)
|
|||
event_del(&w->alerts_timer);
|
||||
|
||||
timerclear(&tv);
|
||||
tv.tv_sec = options_get_number(&w->options, "monitor-silence");
|
||||
tv.tv_sec = options_get_number(w->options, "monitor-silence");
|
||||
|
||||
log_debug("@%u alerts timer reset %u", w->id, (u_int)tv.tv_sec);
|
||||
if (tv.tv_sec != 0)
|
||||
|
|
@ -132,15 +163,15 @@ alerts_queue(struct window *w, int flags)
|
|||
if (!event_initialized(&w->alerts_timer))
|
||||
evtimer_set(&w->alerts_timer, alerts_timer, w);
|
||||
|
||||
if (w->flags & flags)
|
||||
return;
|
||||
w->flags |= flags;
|
||||
log_debug("@%u alerts flags added %#x", w->id, flags);
|
||||
if (!alerts_fired) {
|
||||
w->flags |= flags;
|
||||
log_debug("@%u alerts flags added %#x", w->id, flags);
|
||||
|
||||
if (!alerts_fired && alerts_enabled(w, flags)) {
|
||||
log_debug("alerts check queued (by @%u)", w->id);
|
||||
event_once(-1, EV_TIMEOUT, alerts_callback, NULL, NULL);
|
||||
alerts_fired = 1;
|
||||
if (alerts_enabled(w, flags)) {
|
||||
log_debug("alerts check queued (by @%u)", w->id);
|
||||
event_once(-1, EV_TIMEOUT, alerts_callback, NULL, NULL);
|
||||
alerts_fired = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -151,20 +182,20 @@ alerts_check_bell(struct session *s, struct winlink *wl)
|
|||
struct window *w = wl->window;
|
||||
int action, visual;
|
||||
|
||||
if (!(w->flags & WINDOW_BELL) || wl->flags & WINLINK_BELL)
|
||||
if (!(w->flags & WINDOW_BELL))
|
||||
return (0);
|
||||
if (s->curw != wl || s->flags & SESSION_UNATTACHED)
|
||||
if (s->curw != wl) {
|
||||
wl->flags |= WINLINK_BELL;
|
||||
if (s->flags & SESSION_UNATTACHED)
|
||||
return (0);
|
||||
w->flags &= ~WINDOW_BELL;
|
||||
}
|
||||
if (s->curw->window == w)
|
||||
w->flags &= ~WINDOW_BELL;
|
||||
|
||||
action = options_get_number(&s->options, "bell-action");
|
||||
action = options_get_number(s->options, "bell-action");
|
||||
if (action == BELL_NONE)
|
||||
return (0);
|
||||
|
||||
visual = options_get_number(&s->options, "visual-bell");
|
||||
visual = options_get_number(s->options, "visual-bell");
|
||||
TAILQ_FOREACH(c, &clients, entry) {
|
||||
if (c->session != s || c->flags & CLIENT_CONTROL)
|
||||
continue;
|
||||
|
|
@ -198,17 +229,17 @@ alerts_check_activity(struct session *s, struct winlink *wl)
|
|||
|
||||
if (!(w->flags & WINDOW_ACTIVITY) || wl->flags & WINLINK_ACTIVITY)
|
||||
return (0);
|
||||
if (s->curw == wl && !(s->flags & SESSION_UNATTACHED))
|
||||
if (s->curw == wl)
|
||||
return (0);
|
||||
|
||||
if (!options_get_number(&w->options, "monitor-activity"))
|
||||
if (!options_get_number(w->options, "monitor-activity"))
|
||||
return (0);
|
||||
|
||||
if (options_get_number(&s->options, "bell-on-alert"))
|
||||
if (options_get_number(s->options, "bell-on-alert"))
|
||||
alerts_ring_bell(s);
|
||||
wl->flags |= WINLINK_ACTIVITY;
|
||||
|
||||
if (options_get_number(&s->options, "visual-activity")) {
|
||||
if (options_get_number(s->options, "visual-activity")) {
|
||||
TAILQ_FOREACH(c, &clients, entry) {
|
||||
if (c->session != s)
|
||||
continue;
|
||||
|
|
@ -230,17 +261,17 @@ alerts_check_silence(struct session *s, struct winlink *wl)
|
|||
|
||||
if (!(w->flags & WINDOW_SILENCE) || wl->flags & WINLINK_SILENCE)
|
||||
return (0);
|
||||
if (s->curw == wl && !(s->flags & SESSION_UNATTACHED))
|
||||
if (s->curw == wl)
|
||||
return (0);
|
||||
|
||||
if (options_get_number(&w->options, "monitor-silence") == 0)
|
||||
if (options_get_number(w->options, "monitor-silence") == 0)
|
||||
return (0);
|
||||
|
||||
if (options_get_number(&s->options, "bell-on-alert"))
|
||||
if (options_get_number(s->options, "bell-on-alert"))
|
||||
alerts_ring_bell(s);
|
||||
wl->flags |= WINLINK_SILENCE;
|
||||
|
||||
if (options_get_number(&s->options, "visual-silence")) {
|
||||
if (options_get_number(s->options, "visual-silence")) {
|
||||
TAILQ_FOREACH(c, &clients, entry) {
|
||||
if (c->session != s)
|
||||
continue;
|
||||
|
|
|
|||
88
arguments.c
88
arguments.c
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2010 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2010 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -127,77 +127,73 @@ args_free(struct args *args)
|
|||
free(args);
|
||||
}
|
||||
|
||||
/* Print a set of arguments. */
|
||||
size_t
|
||||
args_print(struct args *args, char *buf, size_t len)
|
||||
/* Add to string. */
|
||||
static void printflike(3, 4)
|
||||
args_print_add(char **buf, size_t *len, const char *fmt, ...)
|
||||
{
|
||||
size_t off, used;
|
||||
va_list ap;
|
||||
char *s;
|
||||
size_t slen;
|
||||
|
||||
va_start(ap, fmt);
|
||||
slen = xvasprintf(&s, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
*len += slen;
|
||||
*buf = xrealloc(*buf, *len);
|
||||
|
||||
strlcat(*buf, s, *len);
|
||||
free(s);
|
||||
}
|
||||
|
||||
/* Print a set of arguments. */
|
||||
char *
|
||||
args_print(struct args *args)
|
||||
{
|
||||
size_t len;
|
||||
char *buf;
|
||||
int i;
|
||||
const char *quotes;
|
||||
struct args_entry *entry;
|
||||
|
||||
/* There must be at least one byte at the start. */
|
||||
if (len == 0)
|
||||
return (0);
|
||||
off = 0;
|
||||
len = 1;
|
||||
buf = xcalloc(1, len);
|
||||
|
||||
/* Process the flags first. */
|
||||
buf[off++] = '-';
|
||||
RB_FOREACH(entry, args_tree, &args->tree) {
|
||||
if (entry->value != NULL)
|
||||
continue;
|
||||
|
||||
if (off == len - 1) {
|
||||
buf[off] = '\0';
|
||||
return (len);
|
||||
}
|
||||
buf[off++] = entry->flag;
|
||||
buf[off] = '\0';
|
||||
if (*buf == '\0')
|
||||
args_print_add(&buf, &len, "-");
|
||||
args_print_add(&buf, &len, "%c", entry->flag);
|
||||
}
|
||||
if (off == 1)
|
||||
buf[--off] = '\0';
|
||||
|
||||
/* Then the flags with arguments. */
|
||||
RB_FOREACH(entry, args_tree, &args->tree) {
|
||||
if (entry->value == NULL)
|
||||
continue;
|
||||
|
||||
if (off >= len) {
|
||||
/* snprintf will have zero terminated. */
|
||||
return (len);
|
||||
}
|
||||
|
||||
if (strchr(entry->value, ' ') != NULL)
|
||||
quotes = "\"";
|
||||
if (*buf != '\0')
|
||||
args_print_add(&buf, &len, " -%c ", entry->flag);
|
||||
else
|
||||
quotes = "";
|
||||
used = xsnprintf(buf + off, len - off, "%s-%c %s%s%s",
|
||||
off != 0 ? " " : "", entry->flag, quotes, entry->value,
|
||||
quotes);
|
||||
if (used > len - off)
|
||||
used = len - off;
|
||||
off += used;
|
||||
args_print_add(&buf, &len, "-%c ", entry->flag);
|
||||
if (strchr(entry->value, ' ') != NULL)
|
||||
args_print_add(&buf, &len, "\"%s\"", entry->value);
|
||||
else
|
||||
args_print_add(&buf, &len, "%s", entry->value);
|
||||
}
|
||||
|
||||
/* And finally the argument vector. */
|
||||
for (i = 0; i < args->argc; i++) {
|
||||
if (off >= len) {
|
||||
/* snprintf will have zero terminated. */
|
||||
return (len);
|
||||
}
|
||||
|
||||
if (*buf != '\0')
|
||||
args_print_add(&buf, &len, " ");
|
||||
if (strchr(args->argv[i], ' ') != NULL)
|
||||
quotes = "\"";
|
||||
args_print_add(&buf, &len, "\"%s\"", args->argv[i]);
|
||||
else
|
||||
quotes = "";
|
||||
used = xsnprintf(buf + off, len - off, "%s%s%s%s",
|
||||
off != 0 ? " " : "", quotes, args->argv[i], quotes);
|
||||
if (used > len - off)
|
||||
used = len - off;
|
||||
off += used;
|
||||
args_print_add(&buf, &len, "%s", args->argv[i]);
|
||||
}
|
||||
|
||||
return (off);
|
||||
return (buf);
|
||||
}
|
||||
|
||||
/* Return if an argument is present. */
|
||||
|
|
|
|||
2
array.h
2
array.h
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2006 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2006 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
|
|||
33
build_static_release.sh
Executable file
33
build_static_release.sh
Executable file
|
|
@ -0,0 +1,33 @@
|
|||
#!/bin/bash
|
||||
set -eux
|
||||
|
||||
# This is invoked by .travis.yml
|
||||
|
||||
VERSION=$1
|
||||
PLATFORM=$2
|
||||
|
||||
SRC_VERSION=`cat configure.ac | grep AC_INIT | sed -E 's/^AC_INIT\(tmate, (.+)\)$/\1/'`
|
||||
|
||||
if [ $SRC_VERSION != $VERSION ]; then
|
||||
echo "Version mismatch: $SRC_VERSION != $VERSION"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
RELEASE_NAME=tmate-$VERSION-static-linux-$PLATFORM
|
||||
echo "Building $RELEASE_NAME"
|
||||
|
||||
docker build . --tag local-$PLATFORM/tmate-build --build-arg PLATFORM=$PLATFORM
|
||||
|
||||
mkdir -p releases
|
||||
cd releases
|
||||
|
||||
rm -rf $RELEASE_NAME
|
||||
mkdir -p $RELEASE_NAME
|
||||
docker run --rm local-$PLATFORM/tmate-build cat /build/tmate > $RELEASE_NAME/tmate
|
||||
chmod +x $RELEASE_NAME/tmate
|
||||
tar -cf - $RELEASE_NAME | xz > tmate-$VERSION-static-linux-$PLATFORM.tar.xz
|
||||
|
||||
rm -rf $RELEASE_NAME-symbols
|
||||
mkdir -p $RELEASE_NAME-symbols
|
||||
docker run --rm local-$PLATFORM/tmate-build cat /build/tmate.symbols > $RELEASE_NAME-symbols/tmate.symbols
|
||||
tar -cf - $RELEASE_NAME-symbols | xz > dbg-symbols-tmate-$VERSION-static-linux-$PLATFORM.tar.xz
|
||||
35
cfg.c
35
cfg.c
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -26,8 +26,12 @@
|
|||
#include <unistd.h>
|
||||
|
||||
#include "tmux.h"
|
||||
#include "tmate.h"
|
||||
|
||||
char *cfg_file;
|
||||
#ifdef TMATE
|
||||
char *tmate_cfg_file;
|
||||
#endif
|
||||
struct cmd_q *cfg_cmd_q;
|
||||
int cfg_finished;
|
||||
int cfg_references;
|
||||
|
|
@ -67,7 +71,7 @@ start_cfg(void)
|
|||
cfg_add_cause("%s: %s", TMUX_CONF, strerror(errno));
|
||||
|
||||
if (cfg_file == NULL && (home = find_home()) != NULL) {
|
||||
xasprintf(&cfg_file, "%s/.tmux.conf", home);
|
||||
xasprintf(&cfg_file, "%s/.tmate.conf", home);
|
||||
if (access(cfg_file, R_OK) != 0 && errno == ENOENT) {
|
||||
free(cfg_file);
|
||||
cfg_file = NULL;
|
||||
|
|
@ -131,13 +135,38 @@ load_cfg(const char *path, struct cmd_q *cmdq, char **cause)
|
|||
return (found);
|
||||
}
|
||||
|
||||
static void print_cfg_errors(void)
|
||||
{
|
||||
u_int i;
|
||||
|
||||
for (i = 0; i < cfg_ncauses; i++) {
|
||||
tmate_info("%s", cfg_causes[i]);
|
||||
free(cfg_causes[i]);
|
||||
}
|
||||
|
||||
free(cfg_causes);
|
||||
cfg_causes = NULL;
|
||||
cfg_ncauses = 0;
|
||||
}
|
||||
|
||||
void
|
||||
cfg_default_done(unused struct cmd_q *cmdq)
|
||||
cfg_default_done(__unused struct cmd_q *cmdq)
|
||||
{
|
||||
if (--cfg_references != 0)
|
||||
return;
|
||||
cfg_finished = 1;
|
||||
|
||||
#ifdef TMATE
|
||||
/* We do it this late, this way, CLI options take precedence over cfg file */
|
||||
tmate_load_cli_options();
|
||||
|
||||
tmate_session_start();
|
||||
if (tmate_foreground && cfg_ncauses) {
|
||||
print_cfg_errors();
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!RB_EMPTY(&sessions))
|
||||
cfg_show_causes(RB_MIN(sessions, &sessions));
|
||||
|
||||
|
|
|
|||
703
client.c
703
client.c
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -32,11 +32,12 @@
|
|||
#include <unistd.h>
|
||||
|
||||
#include "tmux.h"
|
||||
#include "tmate.h"
|
||||
|
||||
int client_flags;
|
||||
struct imsgbuf client_ibuf;
|
||||
struct event client_event;
|
||||
struct event client_stdin;
|
||||
struct tmuxproc *client_proc;
|
||||
struct tmuxpeer *client_peer;
|
||||
int client_flags;
|
||||
struct event client_stdin;
|
||||
enum {
|
||||
CLIENT_EXIT_NONE,
|
||||
CLIENT_EXIT_DETACHED,
|
||||
|
|
@ -47,41 +48,40 @@ enum {
|
|||
CLIENT_EXIT_EXITED,
|
||||
CLIENT_EXIT_SERVER_EXITED,
|
||||
} client_exitreason = CLIENT_EXIT_NONE;
|
||||
int client_exitval;
|
||||
enum msgtype client_exittype;
|
||||
const char *client_exitsession;
|
||||
int client_attached;
|
||||
int client_exitval;
|
||||
enum msgtype client_exittype;
|
||||
const char *client_exitsession;
|
||||
int client_attached;
|
||||
|
||||
__dead void client_exec(const char *);
|
||||
__dead void client_exec(const char *,const char *);
|
||||
int client_get_lock(char *);
|
||||
int client_connect(struct event_base *, char *, int);
|
||||
void client_send_identify(const char *, int);
|
||||
int client_write_one(enum msgtype, int, const void *, size_t);
|
||||
int client_write_server(enum msgtype, const void *, size_t);
|
||||
void client_update_event(void);
|
||||
void client_signal(int, short, void *);
|
||||
int client_connect(struct event_base *, const char *, int);
|
||||
void client_send_identify(const char *, const char *);
|
||||
void client_stdin_callback(int, short, void *);
|
||||
void client_write(int, const char *, size_t);
|
||||
void client_callback(int, short, void *);
|
||||
int client_dispatch_attached(void);
|
||||
int client_dispatch_wait(void);
|
||||
void client_signal(int);
|
||||
void client_dispatch(struct imsg *, void *);
|
||||
void client_dispatch_attached(struct imsg *);
|
||||
void client_dispatch_wait(struct imsg *, const char *);
|
||||
const char *client_exit_message(void);
|
||||
|
||||
/*
|
||||
* Get server create lock. If already held then server start is happening in
|
||||
* another client, so block until the lock is released and return -1 to
|
||||
* retry. Ignore other errors - just continue and start the server without the
|
||||
* lock.
|
||||
* another client, so block until the lock is released and return -2 to
|
||||
* retry. Return -1 on failure to continue and start the server anyway.
|
||||
*/
|
||||
int
|
||||
client_get_lock(char *lockfile)
|
||||
{
|
||||
int lockfd;
|
||||
|
||||
if ((lockfd = open(lockfile, O_WRONLY|O_CREAT, 0600)) == -1)
|
||||
fatal("open failed");
|
||||
log_debug("lock file is %s", lockfile);
|
||||
|
||||
if ((lockfd = open(lockfile, O_WRONLY|O_CREAT, 0600)) == -1) {
|
||||
log_debug("open failed: %s", strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (flock(lockfd, LOCK_EX|LOCK_NB) == -1) {
|
||||
log_debug("flock failed: %s", strerror(errno));
|
||||
if (errno != EAGAIN)
|
||||
|
|
@ -89,7 +89,7 @@ client_get_lock(char *lockfile)
|
|||
while (flock(lockfd, LOCK_EX) == -1 && errno == EINTR)
|
||||
/* nothing */;
|
||||
close(lockfd);
|
||||
return (-1);
|
||||
return (-2);
|
||||
}
|
||||
log_debug("flock succeeded");
|
||||
|
||||
|
|
@ -98,7 +98,7 @@ client_get_lock(char *lockfile)
|
|||
|
||||
/* Connect client to server. */
|
||||
int
|
||||
client_connect(struct event_base *base, char *path, int start_server)
|
||||
client_connect(struct event_base *base, const char *path, int start_server)
|
||||
{
|
||||
struct sockaddr_un sa;
|
||||
size_t size;
|
||||
|
|
@ -116,10 +116,10 @@ client_connect(struct event_base *base, char *path, int start_server)
|
|||
|
||||
retry:
|
||||
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
|
||||
fatal("socket failed");
|
||||
return (-1);
|
||||
|
||||
log_debug("trying connect");
|
||||
if (connect(fd, (struct sockaddr *) &sa, sizeof(sa)) == -1) {
|
||||
if (connect(fd, (struct sockaddr *)&sa, sizeof sa) == -1) {
|
||||
log_debug("connect failed: %s", strerror(errno));
|
||||
if (errno != ECONNREFUSED && errno != ENOENT)
|
||||
goto failed;
|
||||
|
|
@ -129,12 +129,16 @@ retry:
|
|||
|
||||
if (!locked) {
|
||||
xasprintf(&lockfile, "%s.lock", path);
|
||||
if ((lockfd = client_get_lock(lockfile)) == -1) {
|
||||
log_debug("didn't get lock");
|
||||
if ((lockfd = client_get_lock(lockfile)) < 0) {
|
||||
log_debug("didn't get lock (%d)", lockfd);
|
||||
|
||||
free(lockfile);
|
||||
goto retry;
|
||||
lockfile = NULL;
|
||||
|
||||
if (lockfd == -2)
|
||||
goto retry;
|
||||
}
|
||||
log_debug("got lock");
|
||||
log_debug("got lock (%d)", lockfd);
|
||||
|
||||
/*
|
||||
* Always retry at least once, even if we got the lock,
|
||||
|
|
@ -146,7 +150,7 @@ retry:
|
|||
goto retry;
|
||||
}
|
||||
|
||||
if (unlink(path) != 0 && errno != ENOENT) {
|
||||
if (lockfd >= 0 && unlink(path) != 0 && errno != ENOENT) {
|
||||
free(lockfile);
|
||||
close(lockfd);
|
||||
return (-1);
|
||||
|
|
@ -154,7 +158,7 @@ retry:
|
|||
fd = server_start(base, lockfd, lockfile);
|
||||
}
|
||||
|
||||
if (locked) {
|
||||
if (locked && lockfd >= 0) {
|
||||
free(lockfile);
|
||||
close(lockfd);
|
||||
}
|
||||
|
|
@ -207,32 +211,108 @@ client_exit_message(void)
|
|||
return ("unknown reason");
|
||||
}
|
||||
|
||||
#ifdef TMATE
|
||||
extern const struct cmd_entry cmd_attach_session_entry;
|
||||
extern const struct cmd_entry cmd_new_session_entry;
|
||||
|
||||
/* For foreground mode */
|
||||
static int __argc;
|
||||
static const char **__argv;
|
||||
#endif
|
||||
|
||||
int run_headless_command(int argc, const char **argv, int flags, void (*err_callback)(const char *))
|
||||
{
|
||||
struct cmd_q *cmd_q;
|
||||
struct cmd_list *cmdlist;
|
||||
char *cause;
|
||||
cmd_q = cmdq_new(NULL); /* No client */
|
||||
|
||||
if ((cmdlist = cmd_list_parse(argc, (char **)argv, NULL, 0, &cause)) == NULL) {
|
||||
if (err_callback)
|
||||
err_callback(cause);
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmdq_run(cmd_q, cmdlist, NULL);
|
||||
cmd_list_free(cmdlist);
|
||||
cmdq_free(cmd_q);
|
||||
|
||||
if (flags & DEFER_ERRORS_CFG)
|
||||
return 0;
|
||||
|
||||
/* error messages land in cfg_causes */
|
||||
int ret = cfg_ncauses ? -1 : 0;
|
||||
for (u_int i = 0; i < cfg_ncauses; i++) {
|
||||
if (err_callback)
|
||||
err_callback(cfg_causes[i]);
|
||||
free(cfg_causes[i]);
|
||||
}
|
||||
|
||||
free(cfg_causes);
|
||||
cfg_causes = NULL;
|
||||
cfg_ncauses = 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void initial_client_cmd_err_callback(const char *cause)
|
||||
{
|
||||
tmate_info("%s", cause);
|
||||
}
|
||||
|
||||
void run_initial_client_cmd(void)
|
||||
{
|
||||
int argc = __argc;
|
||||
const char **argv = __argv;
|
||||
|
||||
const char *default_argv[] = {"new-session"};
|
||||
if (argc == 0) {
|
||||
argc = 1;
|
||||
argv = default_argv;
|
||||
}
|
||||
|
||||
if (run_headless_command(argc, argv, 0, initial_client_cmd_err_callback) < 0)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Client main loop. */
|
||||
int
|
||||
client_main(struct event_base *base, int argc, char **argv, int flags)
|
||||
client_main(struct event_base *base, int argc, char **argv, int flags,
|
||||
const char *shellcmd)
|
||||
{
|
||||
struct cmd *cmd;
|
||||
struct cmd_list *cmdlist;
|
||||
struct msg_command_data *data;
|
||||
int cmdflags, fd, i, cwd;
|
||||
const char* ttynam;
|
||||
int cmdflags, fd, i;
|
||||
const char *ttynam, *cwd;
|
||||
pid_t ppid;
|
||||
enum msgtype msg;
|
||||
char *cause;
|
||||
char *cause, path[PATH_MAX];
|
||||
struct termios tio, saved_tio;
|
||||
size_t size;
|
||||
#ifdef TMATE
|
||||
int cant_nest = 0;
|
||||
__argc = argc;
|
||||
__argv = (const char **)argv;
|
||||
#endif
|
||||
|
||||
/* Ignore SIGCHLD now or daemon() in the server will leave a zombie. */
|
||||
signal(SIGCHLD, SIG_IGN);
|
||||
|
||||
/* Save the flags. */
|
||||
client_flags = flags;
|
||||
|
||||
/* Set up the initial command. */
|
||||
cmdflags = 0;
|
||||
if (shell_cmd != NULL) {
|
||||
if (shellcmd != NULL) {
|
||||
msg = MSG_SHELL;
|
||||
cmdflags = CMD_STARTSERVER;
|
||||
} else if (argc == 0) {
|
||||
msg = MSG_COMMAND;
|
||||
cmdflags = CMD_STARTSERVER;
|
||||
#ifdef TMATE
|
||||
cant_nest = 1;
|
||||
#endif
|
||||
} else {
|
||||
msg = MSG_COMMAND;
|
||||
|
||||
|
|
@ -250,12 +330,26 @@ client_main(struct event_base *base, int argc, char **argv, int flags)
|
|||
TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
|
||||
if (cmd->entry->flags & CMD_STARTSERVER)
|
||||
cmdflags |= CMD_STARTSERVER;
|
||||
|
||||
#ifdef TMATE
|
||||
if (cmd->entry == &cmd_attach_session_entry ||
|
||||
cmd->entry == &cmd_new_session_entry)
|
||||
cant_nest = 1;
|
||||
#endif
|
||||
}
|
||||
cmd_list_free(cmdlist);
|
||||
}
|
||||
|
||||
/* Establish signal handlers. */
|
||||
set_signals(client_signal);
|
||||
#ifdef TMATE
|
||||
if (cant_nest && getenv("TMUX")) {
|
||||
fprintf(stderr, "sessions should be nested with care, "
|
||||
"unset $TMUX to force\n");
|
||||
return (1);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Create client process structure (starts logging). */
|
||||
client_proc = proc_start("client", base, 0, client_signal);
|
||||
|
||||
/* Initialize the client socket and start the server. */
|
||||
fd = client_connect(base, socket_path, cmdflags & CMD_STARTSERVER);
|
||||
|
|
@ -264,15 +358,26 @@ client_main(struct event_base *base, int argc, char **argv, int flags)
|
|||
fprintf(stderr, "no server running on %s\n",
|
||||
socket_path);
|
||||
} else {
|
||||
#ifdef TMATE
|
||||
if (errno == ENOENT)
|
||||
fprintf(stderr, "You must specify a socket name with -S. For example: \n"
|
||||
" tmate -S /tmp/tmate.sock new-session -d\n"
|
||||
" tmate -S /tmp/tmate.sock wait tmate-ready\n");
|
||||
else
|
||||
#endif
|
||||
fprintf(stderr, "error connecting to %s (%s)\n",
|
||||
socket_path, strerror(errno));
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
client_peer = proc_add_peer(client_proc, fd, client_dispatch,
|
||||
(void *)shellcmd);
|
||||
|
||||
/* Save these before pledge(). */
|
||||
if ((cwd = open(".", O_RDONLY)) == -1)
|
||||
cwd = open("/", O_RDONLY);
|
||||
if ((cwd = getcwd(path, sizeof path)) == NULL) {
|
||||
if ((cwd = find_home()) == NULL)
|
||||
cwd = "/";
|
||||
}
|
||||
if ((ttynam = ttyname(STDIN_FILENO)) == NULL)
|
||||
ttynam = "";
|
||||
|
||||
|
|
@ -291,31 +396,18 @@ client_main(struct event_base *base, int argc, char **argv, int flags)
|
|||
#endif
|
||||
|
||||
/* Free stuff that is not used in the client. */
|
||||
options_free(&global_options);
|
||||
options_free(&global_s_options);
|
||||
options_free(&global_w_options);
|
||||
environ_free(&global_environ);
|
||||
|
||||
/* Set process title, log and signals now this is the client. */
|
||||
#ifdef HAVE_SETPROCTITLE
|
||||
setproctitle("client (%s)", socket_path);
|
||||
#endif
|
||||
logfile("client");
|
||||
|
||||
/* Create imsg. */
|
||||
imsg_init(&client_ibuf, fd);
|
||||
event_set(&client_event, fd, EV_READ, client_callback, NULL);
|
||||
options_free(global_options);
|
||||
options_free(global_s_options);
|
||||
options_free(global_w_options);
|
||||
environ_free(global_environ);
|
||||
|
||||
/* Create stdin handler. */
|
||||
setblocking(STDIN_FILENO, 0);
|
||||
event_set(&client_stdin, STDIN_FILENO, EV_READ|EV_PERSIST,
|
||||
client_stdin_callback, NULL);
|
||||
if (client_flags & CLIENT_CONTROLCONTROL) {
|
||||
if (tcgetattr(STDIN_FILENO, &saved_tio) != 0) {
|
||||
fprintf(stderr, "tcgetattr failed: %s\n",
|
||||
strerror(errno));
|
||||
return (1);
|
||||
}
|
||||
if (tcgetattr(STDIN_FILENO, &saved_tio) != 0)
|
||||
fatal("tcgetattr failed");
|
||||
cfmakeraw(&tio);
|
||||
tio.c_iflag = ICRNL|IXANY;
|
||||
tio.c_oflag = OPOST|ONLCR;
|
||||
|
|
@ -331,7 +423,7 @@ client_main(struct event_base *base, int argc, char **argv, int flags)
|
|||
}
|
||||
|
||||
/* Send identify messages. */
|
||||
client_send_identify(ttynam, cwd); /* closes cwd */
|
||||
client_send_identify(ttynam, cwd);
|
||||
|
||||
/* Send first command. */
|
||||
if (msg == MSG_COMMAND) {
|
||||
|
|
@ -351,18 +443,17 @@ client_main(struct event_base *base, int argc, char **argv, int flags)
|
|||
size += sizeof *data;
|
||||
|
||||
/* Send the command. */
|
||||
if (client_write_server(msg, data, size) != 0) {
|
||||
if (proc_send(client_peer, msg, -1, data, size) != 0) {
|
||||
fprintf(stderr, "failed to send command\n");
|
||||
free(data);
|
||||
return (1);
|
||||
}
|
||||
free(data);
|
||||
} else if (msg == MSG_SHELL)
|
||||
client_write_server(msg, NULL, 0);
|
||||
proc_send(client_peer, msg, -1, NULL, 0);
|
||||
|
||||
/* Set the event and dispatch. */
|
||||
client_update_event();
|
||||
event_dispatch();
|
||||
/* Start main loop. */
|
||||
proc_loop(client_proc, NULL);
|
||||
|
||||
/* Print the exit message, if any, and exit. */
|
||||
if (client_attached) {
|
||||
|
|
@ -379,14 +470,15 @@ client_main(struct event_base *base, int argc, char **argv, int flags)
|
|||
printf("%%exit\n");
|
||||
printf("\033\\");
|
||||
tcsetattr(STDOUT_FILENO, TCSAFLUSH, &saved_tio);
|
||||
}
|
||||
} else if (client_exitreason != CLIENT_EXIT_NONE)
|
||||
fprintf(stderr, "%s\n", client_exit_message());
|
||||
setblocking(STDIN_FILENO, 1);
|
||||
return (client_exitval);
|
||||
}
|
||||
|
||||
/* Send identify messages to server. */
|
||||
void
|
||||
client_send_identify(const char *ttynam, int cwd)
|
||||
client_send_identify(const char *ttynam, const char *cwd)
|
||||
{
|
||||
const char *s;
|
||||
char **ss;
|
||||
|
|
@ -394,149 +486,37 @@ client_send_identify(const char *ttynam, int cwd)
|
|||
int fd, flags = client_flags;
|
||||
pid_t pid;
|
||||
|
||||
client_write_one(MSG_IDENTIFY_FLAGS, -1, &flags, sizeof flags);
|
||||
proc_send(client_peer, MSG_IDENTIFY_FLAGS, -1, &flags, sizeof flags);
|
||||
|
||||
if ((s = getenv("TERM")) == NULL)
|
||||
s = "";
|
||||
client_write_one(MSG_IDENTIFY_TERM, -1, s, strlen(s) + 1);
|
||||
proc_send(client_peer, MSG_IDENTIFY_TERM, -1, s, strlen(s) + 1);
|
||||
|
||||
client_write_one(MSG_IDENTIFY_TTYNAME, -1, ttynam, strlen(ttynam) + 1);
|
||||
client_write_one(MSG_IDENTIFY_CWD, cwd, NULL, 0);
|
||||
proc_send(client_peer, MSG_IDENTIFY_TTYNAME, -1, ttynam,
|
||||
strlen(ttynam) + 1);
|
||||
proc_send(client_peer, MSG_IDENTIFY_CWD, -1, cwd, strlen(cwd) + 1);
|
||||
|
||||
if ((fd = dup(STDIN_FILENO)) == -1)
|
||||
fatal("dup failed");
|
||||
client_write_one(MSG_IDENTIFY_STDIN, fd, NULL, 0);
|
||||
proc_send(client_peer, MSG_IDENTIFY_STDIN, fd, NULL, 0);
|
||||
|
||||
pid = getpid();
|
||||
client_write_one(MSG_IDENTIFY_CLIENTPID, -1, &pid, sizeof pid);
|
||||
proc_send(client_peer, MSG_IDENTIFY_CLIENTPID, -1, &pid, sizeof pid);
|
||||
|
||||
for (ss = environ; *ss != NULL; ss++) {
|
||||
sslen = strlen(*ss) + 1;
|
||||
if (sslen <= MAX_IMSGSIZE - IMSG_HEADER_SIZE)
|
||||
client_write_one(MSG_IDENTIFY_ENVIRON, -1, *ss, sslen);
|
||||
if (sslen > MAX_IMSGSIZE - IMSG_HEADER_SIZE)
|
||||
continue;
|
||||
proc_send(client_peer, MSG_IDENTIFY_ENVIRON, -1, *ss, sslen);
|
||||
}
|
||||
|
||||
client_write_one(MSG_IDENTIFY_DONE, -1, NULL, 0);
|
||||
}
|
||||
|
||||
/* Helper to send one message. */
|
||||
int
|
||||
client_write_one(enum msgtype type, int fd, const void *buf, size_t len)
|
||||
{
|
||||
int retval;
|
||||
|
||||
retval = imsg_compose(&client_ibuf, type, PROTOCOL_VERSION, -1, fd,
|
||||
(void *)buf, len);
|
||||
if (retval != 1)
|
||||
return (-1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Write a message to the server without a file descriptor. */
|
||||
int
|
||||
client_write_server(enum msgtype type, const void *buf, size_t len)
|
||||
{
|
||||
int retval;
|
||||
|
||||
retval = client_write_one(type, -1, buf, len);
|
||||
if (retval == 0)
|
||||
client_update_event();
|
||||
return (retval);
|
||||
}
|
||||
|
||||
/* Update client event based on whether it needs to read or read and write. */
|
||||
void
|
||||
client_update_event(void)
|
||||
{
|
||||
short events;
|
||||
|
||||
event_del(&client_event);
|
||||
events = EV_READ;
|
||||
if (client_ibuf.w.queued > 0)
|
||||
events |= EV_WRITE;
|
||||
event_set(&client_event, client_ibuf.fd, events, client_callback, NULL);
|
||||
event_add(&client_event, NULL);
|
||||
}
|
||||
|
||||
/* Callback to handle signals in the client. */
|
||||
void
|
||||
client_signal(int sig, unused short events, unused void *arg)
|
||||
{
|
||||
struct sigaction sigact;
|
||||
int status;
|
||||
|
||||
if (sig == SIGCHLD)
|
||||
waitpid(WAIT_ANY, &status, WNOHANG);
|
||||
else if (!client_attached) {
|
||||
if (sig == SIGTERM)
|
||||
event_loopexit(NULL);
|
||||
} else {
|
||||
switch (sig) {
|
||||
case SIGHUP:
|
||||
client_exitreason = CLIENT_EXIT_LOST_TTY;
|
||||
client_exitval = 1;
|
||||
client_write_server(MSG_EXITING, NULL, 0);
|
||||
break;
|
||||
case SIGTERM:
|
||||
client_exitreason = CLIENT_EXIT_TERMINATED;
|
||||
client_exitval = 1;
|
||||
client_write_server(MSG_EXITING, NULL, 0);
|
||||
break;
|
||||
case SIGWINCH:
|
||||
client_write_server(MSG_RESIZE, NULL, 0);
|
||||
break;
|
||||
case SIGCONT:
|
||||
memset(&sigact, 0, sizeof sigact);
|
||||
sigemptyset(&sigact.sa_mask);
|
||||
sigact.sa_flags = SA_RESTART;
|
||||
sigact.sa_handler = SIG_IGN;
|
||||
if (sigaction(SIGTSTP, &sigact, NULL) != 0)
|
||||
fatal("sigaction failed");
|
||||
client_write_server(MSG_WAKEUP, NULL, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
client_update_event();
|
||||
}
|
||||
|
||||
/* Callback for client imsg read events. */
|
||||
void
|
||||
client_callback(unused int fd, short events, unused void *arg)
|
||||
{
|
||||
ssize_t n;
|
||||
int retval;
|
||||
|
||||
if (events & EV_READ) {
|
||||
if ((n = imsg_read(&client_ibuf)) == -1 || n == 0)
|
||||
goto lost_server;
|
||||
if (client_attached)
|
||||
retval = client_dispatch_attached();
|
||||
else
|
||||
retval = client_dispatch_wait();
|
||||
if (retval != 0) {
|
||||
event_loopexit(NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (events & EV_WRITE) {
|
||||
if (msgbuf_write(&client_ibuf.w) <= 0 && errno != EAGAIN)
|
||||
goto lost_server;
|
||||
}
|
||||
|
||||
client_update_event();
|
||||
return;
|
||||
|
||||
lost_server:
|
||||
client_exitreason = CLIENT_EXIT_LOST_SERVER;
|
||||
client_exitval = 1;
|
||||
event_loopexit(NULL);
|
||||
proc_send(client_peer, MSG_IDENTIFY_DONE, -1, NULL, 0);
|
||||
}
|
||||
|
||||
/* Callback for client stdin read events. */
|
||||
void
|
||||
client_stdin_callback(unused int fd, unused short events, unused void *arg)
|
||||
client_stdin_callback(__unused int fd, __unused short events,
|
||||
__unused void *arg)
|
||||
{
|
||||
struct msg_stdin_data data;
|
||||
|
||||
|
|
@ -544,10 +524,9 @@ client_stdin_callback(unused int fd, unused short events, unused void *arg)
|
|||
if (data.size < 0 && (errno == EINTR || errno == EAGAIN))
|
||||
return;
|
||||
|
||||
client_write_server(MSG_STDIN, &data, sizeof data);
|
||||
proc_send(client_peer, MSG_STDIN, -1, &data, sizeof data);
|
||||
if (data.size <= 0)
|
||||
event_del(&client_stdin);
|
||||
client_update_event();
|
||||
}
|
||||
|
||||
/* Force write to file descriptor. */
|
||||
|
|
@ -570,12 +549,12 @@ client_write(int fd, const char *data, size_t size)
|
|||
|
||||
/* Run command in shell; used for -c. */
|
||||
__dead void
|
||||
client_exec(const char *shell)
|
||||
client_exec(const char *shell, const char *shellcmd)
|
||||
{
|
||||
const char *name, *ptr;
|
||||
char *argv0;
|
||||
|
||||
log_debug("shell %s, command %s", shell, shell_cmd);
|
||||
log_debug("shell %s, command %s", shell, shellcmd);
|
||||
|
||||
ptr = strrchr(shell, '/');
|
||||
if (ptr != NULL && *(ptr + 1) != '\0')
|
||||
|
|
@ -593,17 +572,73 @@ client_exec(const char *shell)
|
|||
setblocking(STDERR_FILENO, 1);
|
||||
closefrom(STDERR_FILENO + 1);
|
||||
|
||||
execl(shell, argv0, "-c", shell_cmd, (char *) NULL);
|
||||
execl(shell, argv0, "-c", shellcmd, (char *) NULL);
|
||||
fatal("execl failed");
|
||||
}
|
||||
|
||||
/* Dispatch imsgs when in wait state (before MSG_READY). */
|
||||
int
|
||||
client_dispatch_wait(void)
|
||||
/* Callback to handle signals in the client. */
|
||||
void
|
||||
client_signal(int sig)
|
||||
{
|
||||
struct sigaction sigact;
|
||||
int status;
|
||||
|
||||
if (sig == SIGCHLD)
|
||||
waitpid(WAIT_ANY, &status, WNOHANG);
|
||||
else if (!client_attached) {
|
||||
if (sig == SIGTERM)
|
||||
proc_exit(client_proc);
|
||||
} else {
|
||||
switch (sig) {
|
||||
case SIGHUP:
|
||||
client_exitreason = CLIENT_EXIT_LOST_TTY;
|
||||
client_exitval = 1;
|
||||
proc_send(client_peer, MSG_EXITING, -1, NULL, 0);
|
||||
break;
|
||||
case SIGTERM:
|
||||
client_exitreason = CLIENT_EXIT_TERMINATED;
|
||||
client_exitval = 1;
|
||||
proc_send(client_peer, MSG_EXITING, -1, NULL, 0);
|
||||
break;
|
||||
case SIGWINCH:
|
||||
proc_send(client_peer, MSG_RESIZE, -1, NULL, 0);
|
||||
break;
|
||||
case SIGCONT:
|
||||
memset(&sigact, 0, sizeof sigact);
|
||||
sigemptyset(&sigact.sa_mask);
|
||||
sigact.sa_flags = SA_RESTART;
|
||||
sigact.sa_handler = SIG_IGN;
|
||||
if (sigaction(SIGTSTP, &sigact, NULL) != 0)
|
||||
fatal("sigaction failed");
|
||||
proc_send(client_peer, MSG_WAKEUP, -1, NULL, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Callback for client read events. */
|
||||
void
|
||||
client_dispatch(struct imsg *imsg, void *arg)
|
||||
{
|
||||
if (imsg == NULL) {
|
||||
client_exitreason = CLIENT_EXIT_LOST_SERVER;
|
||||
client_exitval = 1;
|
||||
proc_exit(client_proc);
|
||||
return;
|
||||
}
|
||||
|
||||
if (client_attached)
|
||||
client_dispatch_attached(imsg);
|
||||
else
|
||||
client_dispatch_wait(imsg, arg);
|
||||
}
|
||||
|
||||
/* Dispatch imsgs when in wait state (before MSG_READY). */
|
||||
void
|
||||
client_dispatch_wait(struct imsg *imsg, const char *shellcmd)
|
||||
{
|
||||
struct imsg imsg;
|
||||
char *data;
|
||||
ssize_t n, datalen;
|
||||
ssize_t datalen;
|
||||
struct msg_stdout_data stdoutdata;
|
||||
struct msg_stderr_data stderrdata;
|
||||
int retval;
|
||||
|
|
@ -623,163 +658,141 @@ client_dispatch_wait(void)
|
|||
};
|
||||
#endif
|
||||
|
||||
for (;;) {
|
||||
if ((n = imsg_get(&client_ibuf, &imsg)) == -1)
|
||||
fatalx("imsg_get failed");
|
||||
if (n == 0)
|
||||
return (0);
|
||||
data = imsg->data;
|
||||
datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
|
||||
|
||||
data = imsg.data;
|
||||
datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
|
||||
|
||||
log_debug("got %u from server", imsg.hdr.type);
|
||||
switch (imsg.hdr.type) {
|
||||
case MSG_EXIT:
|
||||
case MSG_SHUTDOWN:
|
||||
if (datalen != sizeof retval && datalen != 0)
|
||||
fatalx("bad MSG_EXIT size");
|
||||
if (datalen == sizeof retval) {
|
||||
memcpy(&retval, data, sizeof retval);
|
||||
client_exitval = retval;
|
||||
}
|
||||
imsg_free(&imsg);
|
||||
return (-1);
|
||||
case MSG_READY:
|
||||
if (datalen != 0)
|
||||
fatalx("bad MSG_READY size");
|
||||
|
||||
event_del(&client_stdin);
|
||||
client_attached = 1;
|
||||
client_write_server(MSG_RESIZE, NULL, 0);
|
||||
break;
|
||||
case MSG_STDIN:
|
||||
if (datalen != 0)
|
||||
fatalx("bad MSG_STDIN size");
|
||||
|
||||
event_add(&client_stdin, NULL);
|
||||
break;
|
||||
case MSG_STDOUT:
|
||||
if (datalen != sizeof stdoutdata)
|
||||
fatalx("bad MSG_STDOUT size");
|
||||
memcpy(&stdoutdata, data, sizeof stdoutdata);
|
||||
|
||||
client_write(STDOUT_FILENO, stdoutdata.data,
|
||||
stdoutdata.size);
|
||||
break;
|
||||
case MSG_STDERR:
|
||||
if (datalen != sizeof stderrdata)
|
||||
fatalx("bad MSG_STDERR size");
|
||||
memcpy(&stderrdata, data, sizeof stderrdata);
|
||||
|
||||
client_write(STDERR_FILENO, stderrdata.data,
|
||||
stderrdata.size);
|
||||
break;
|
||||
case MSG_VERSION:
|
||||
if (datalen != 0)
|
||||
fatalx("bad MSG_VERSION size");
|
||||
|
||||
fprintf(stderr, "protocol version mismatch "
|
||||
"(client %d, server %u)\n", PROTOCOL_VERSION,
|
||||
imsg.hdr.peerid);
|
||||
client_exitval = 1;
|
||||
|
||||
imsg_free(&imsg);
|
||||
return (-1);
|
||||
case MSG_SHELL:
|
||||
if (datalen == 0 || data[datalen - 1] != '\0')
|
||||
fatalx("bad MSG_SHELL string");
|
||||
|
||||
clear_signals(0);
|
||||
client_exec(data);
|
||||
/* NOTREACHED */
|
||||
case MSG_DETACH:
|
||||
case MSG_DETACHKILL:
|
||||
client_write_server(MSG_EXITING, NULL, 0);
|
||||
break;
|
||||
case MSG_EXITED:
|
||||
imsg_free(&imsg);
|
||||
return (-1);
|
||||
switch (imsg->hdr.type) {
|
||||
case MSG_EXIT:
|
||||
case MSG_SHUTDOWN:
|
||||
if (datalen != sizeof retval && datalen != 0)
|
||||
fatalx("bad MSG_EXIT size");
|
||||
if (datalen == sizeof retval) {
|
||||
memcpy(&retval, data, sizeof retval);
|
||||
client_exitval = retval;
|
||||
}
|
||||
proc_exit(client_proc);
|
||||
break;
|
||||
case MSG_READY:
|
||||
if (datalen != 0)
|
||||
fatalx("bad MSG_READY size");
|
||||
|
||||
imsg_free(&imsg);
|
||||
event_del(&client_stdin);
|
||||
client_attached = 1;
|
||||
proc_send(client_peer, MSG_RESIZE, -1, NULL, 0);
|
||||
break;
|
||||
case MSG_STDIN:
|
||||
if (datalen != 0)
|
||||
fatalx("bad MSG_STDIN size");
|
||||
|
||||
event_add(&client_stdin, NULL);
|
||||
break;
|
||||
case MSG_STDOUT:
|
||||
if (datalen != sizeof stdoutdata)
|
||||
fatalx("bad MSG_STDOUT size");
|
||||
memcpy(&stdoutdata, data, sizeof stdoutdata);
|
||||
|
||||
client_write(STDOUT_FILENO, stdoutdata.data,
|
||||
stdoutdata.size);
|
||||
break;
|
||||
case MSG_STDERR:
|
||||
if (datalen != sizeof stderrdata)
|
||||
fatalx("bad MSG_STDERR size");
|
||||
memcpy(&stderrdata, data, sizeof stderrdata);
|
||||
|
||||
client_write(STDERR_FILENO, stderrdata.data,
|
||||
stderrdata.size);
|
||||
break;
|
||||
case MSG_VERSION:
|
||||
if (datalen != 0)
|
||||
fatalx("bad MSG_VERSION size");
|
||||
|
||||
fprintf(stderr, "protocol version mismatch "
|
||||
"(client %d, server %u)\n", PROTOCOL_VERSION,
|
||||
imsg->hdr.peerid & 0xff);
|
||||
client_exitval = 1;
|
||||
proc_exit(client_proc);
|
||||
break;
|
||||
case MSG_SHELL:
|
||||
if (datalen == 0 || data[datalen - 1] != '\0')
|
||||
fatalx("bad MSG_SHELL string");
|
||||
|
||||
clear_signals(0);
|
||||
client_exec(data, shellcmd);
|
||||
/* NOTREACHED */
|
||||
case MSG_DETACH:
|
||||
case MSG_DETACHKILL:
|
||||
proc_send(client_peer, MSG_EXITING, -1, NULL, 0);
|
||||
break;
|
||||
case MSG_EXITED:
|
||||
proc_exit(client_proc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Dispatch imsgs in attached state (after MSG_READY). */
|
||||
int
|
||||
client_dispatch_attached(void)
|
||||
void
|
||||
client_dispatch_attached(struct imsg *imsg)
|
||||
{
|
||||
struct imsg imsg;
|
||||
struct sigaction sigact;
|
||||
char *data;
|
||||
ssize_t n, datalen;
|
||||
ssize_t datalen;
|
||||
|
||||
for (;;) {
|
||||
if ((n = imsg_get(&client_ibuf, &imsg)) == -1)
|
||||
fatalx("imsg_get failed");
|
||||
if (n == 0)
|
||||
return (0);
|
||||
data = imsg->data;
|
||||
datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
|
||||
|
||||
data = imsg.data;
|
||||
datalen = imsg.hdr.len - IMSG_HEADER_SIZE;
|
||||
switch (imsg->hdr.type) {
|
||||
case MSG_DETACH:
|
||||
case MSG_DETACHKILL:
|
||||
if (datalen == 0 || data[datalen - 1] != '\0')
|
||||
fatalx("bad MSG_DETACH string");
|
||||
|
||||
log_debug("got %u from server", imsg.hdr.type);
|
||||
switch (imsg.hdr.type) {
|
||||
case MSG_DETACH:
|
||||
case MSG_DETACHKILL:
|
||||
if (datalen == 0 || data[datalen - 1] != '\0')
|
||||
fatalx("bad MSG_DETACH string");
|
||||
client_exitsession = xstrdup(data);
|
||||
client_exittype = imsg->hdr.type;
|
||||
if (imsg->hdr.type == MSG_DETACHKILL)
|
||||
client_exitreason = CLIENT_EXIT_DETACHED_HUP;
|
||||
else
|
||||
client_exitreason = CLIENT_EXIT_DETACHED;
|
||||
proc_send(client_peer, MSG_EXITING, -1, NULL, 0);
|
||||
break;
|
||||
case MSG_EXIT:
|
||||
if (datalen != 0 && datalen != sizeof (int))
|
||||
fatalx("bad MSG_EXIT size");
|
||||
|
||||
client_exitsession = xstrdup(data);
|
||||
client_exittype = imsg.hdr.type;
|
||||
if (imsg.hdr.type == MSG_DETACHKILL)
|
||||
client_exitreason = CLIENT_EXIT_DETACHED_HUP;
|
||||
else
|
||||
client_exitreason = CLIENT_EXIT_DETACHED;
|
||||
client_write_server(MSG_EXITING, NULL, 0);
|
||||
break;
|
||||
case MSG_EXIT:
|
||||
if (datalen != 0 && datalen != sizeof (int))
|
||||
fatalx("bad MSG_EXIT size");
|
||||
proc_send(client_peer, MSG_EXITING, -1, NULL, 0);
|
||||
client_exitreason = CLIENT_EXIT_EXITED;
|
||||
break;
|
||||
case MSG_EXITED:
|
||||
if (datalen != 0)
|
||||
fatalx("bad MSG_EXITED size");
|
||||
|
||||
client_write_server(MSG_EXITING, NULL, 0);
|
||||
client_exitreason = CLIENT_EXIT_EXITED;
|
||||
break;
|
||||
case MSG_EXITED:
|
||||
if (datalen != 0)
|
||||
fatalx("bad MSG_EXITED size");
|
||||
proc_exit(client_proc);
|
||||
break;
|
||||
case MSG_SHUTDOWN:
|
||||
if (datalen != 0)
|
||||
fatalx("bad MSG_SHUTDOWN size");
|
||||
|
||||
imsg_free(&imsg);
|
||||
return (-1);
|
||||
case MSG_SHUTDOWN:
|
||||
if (datalen != 0)
|
||||
fatalx("bad MSG_SHUTDOWN size");
|
||||
proc_send(client_peer, MSG_EXITING, -1, NULL, 0);
|
||||
client_exitreason = CLIENT_EXIT_SERVER_EXITED;
|
||||
client_exitval = 1;
|
||||
break;
|
||||
case MSG_SUSPEND:
|
||||
if (datalen != 0)
|
||||
fatalx("bad MSG_SUSPEND size");
|
||||
|
||||
client_write_server(MSG_EXITING, NULL, 0);
|
||||
client_exitreason = CLIENT_EXIT_SERVER_EXITED;
|
||||
client_exitval = 1;
|
||||
break;
|
||||
case MSG_SUSPEND:
|
||||
if (datalen != 0)
|
||||
fatalx("bad MSG_SUSPEND size");
|
||||
memset(&sigact, 0, sizeof sigact);
|
||||
sigemptyset(&sigact.sa_mask);
|
||||
sigact.sa_flags = SA_RESTART;
|
||||
sigact.sa_handler = SIG_DFL;
|
||||
if (sigaction(SIGTSTP, &sigact, NULL) != 0)
|
||||
fatal("sigaction failed");
|
||||
kill(getpid(), SIGTSTP);
|
||||
break;
|
||||
case MSG_LOCK:
|
||||
if (datalen == 0 || data[datalen - 1] != '\0')
|
||||
fatalx("bad MSG_LOCK string");
|
||||
|
||||
memset(&sigact, 0, sizeof sigact);
|
||||
sigemptyset(&sigact.sa_mask);
|
||||
sigact.sa_flags = SA_RESTART;
|
||||
sigact.sa_handler = SIG_DFL;
|
||||
if (sigaction(SIGTSTP, &sigact, NULL) != 0)
|
||||
fatal("sigaction failed");
|
||||
kill(getpid(), SIGTSTP);
|
||||
break;
|
||||
case MSG_LOCK:
|
||||
if (datalen == 0 || data[datalen - 1] != '\0')
|
||||
fatalx("bad MSG_LOCK string");
|
||||
|
||||
system(data);
|
||||
client_write_server(MSG_UNLOCK, NULL, 0);
|
||||
break;
|
||||
}
|
||||
|
||||
imsg_free(&imsg);
|
||||
system(data);
|
||||
proc_send(client_peer, MSG_UNLOCK, -1, NULL, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -33,52 +33,35 @@
|
|||
enum cmd_retval cmd_attach_session_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_attach_session_entry = {
|
||||
"attach-session", "attach",
|
||||
"c:dErt:", 0, 0,
|
||||
"[-dEr] [-c working-directory] " CMD_TARGET_SESSION_USAGE,
|
||||
CMD_STARTSERVER,
|
||||
cmd_attach_session_exec
|
||||
.name = "attach-session",
|
||||
.alias = "attach",
|
||||
|
||||
.args = { "c:dErt:", 0, 0 },
|
||||
.usage = "[-dEr] [-c working-directory] " CMD_TARGET_SESSION_USAGE,
|
||||
|
||||
.tflag = CMD_SESSION_WITHPANE,
|
||||
|
||||
.flags = CMD_STARTSERVER,
|
||||
.exec = cmd_attach_session_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int dflag, int rflag,
|
||||
const char *cflag, int Eflag)
|
||||
cmd_attach_session(struct cmd_q *cmdq, int dflag, int rflag, const char *cflag,
|
||||
int Eflag)
|
||||
{
|
||||
struct session *s;
|
||||
struct session *s = cmdq->state.tflag.s;
|
||||
struct client *c = cmdq->client, *c_loop;
|
||||
struct winlink *wl = NULL;
|
||||
struct window *w = NULL;
|
||||
struct window_pane *wp = NULL;
|
||||
struct winlink *wl = cmdq->state.tflag.wl;
|
||||
struct window_pane *wp = cmdq->state.tflag.wp;
|
||||
const char *update;
|
||||
char *cause;
|
||||
int fd;
|
||||
char *cause, *cwd;
|
||||
struct format_tree *ft;
|
||||
char *cp;
|
||||
|
||||
if (RB_EMPTY(&sessions)) {
|
||||
cmdq_error(cmdq, "no sessions");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
if (tflag == NULL) {
|
||||
if ((s = cmd_find_session(cmdq, tflag, 1)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
} else if (tflag[strcspn(tflag, ":.")] != '\0') {
|
||||
if ((wl = cmd_find_pane(cmdq, tflag, &s, &wp)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
} else {
|
||||
if ((s = cmd_find_session(cmdq, tflag, 1)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
w = window_find_by_id_str(tflag);
|
||||
if (w == NULL) {
|
||||
wp = window_pane_find_by_id_str(tflag);
|
||||
if (wp != NULL)
|
||||
w = wp->window;
|
||||
}
|
||||
if (w != NULL)
|
||||
wl = winlink_find_by_window(&s->windows, w);
|
||||
}
|
||||
|
||||
if (c == NULL)
|
||||
return (CMD_RETURN_NORMAL);
|
||||
if (server_client_check_nested(c)) {
|
||||
|
|
@ -94,45 +77,32 @@ cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int dflag, int rflag,
|
|||
}
|
||||
|
||||
if (cflag != NULL) {
|
||||
ft = format_create();
|
||||
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s,
|
||||
NULL, NULL);
|
||||
cp = format_expand(ft, cflag);
|
||||
ft = format_create(cmdq, 0);
|
||||
format_defaults(ft, c, s, wl, wp);
|
||||
cwd = format_expand(ft, cflag);
|
||||
format_free(ft);
|
||||
|
||||
fd = open(cp, O_RDONLY|O_DIRECTORY);
|
||||
free(cp);
|
||||
if (fd == -1) {
|
||||
cmdq_error(cmdq, "bad working directory: %s",
|
||||
strerror(errno));
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
close(s->cwd);
|
||||
s->cwd = fd;
|
||||
free((void *)s->cwd);
|
||||
s->cwd = cwd;
|
||||
}
|
||||
|
||||
if (c->session != NULL) {
|
||||
if (dflag) {
|
||||
/*
|
||||
* Can't use server_write_session in case attaching to
|
||||
* the same session as currently attached to.
|
||||
*/
|
||||
TAILQ_FOREACH(c_loop, &clients, entry) {
|
||||
if (c_loop->session != s || c == c_loop)
|
||||
continue;
|
||||
server_write_client(c, MSG_DETACH,
|
||||
c_loop->session->name,
|
||||
strlen(c_loop->session->name) + 1);
|
||||
server_client_detach(c_loop, MSG_DETACH);
|
||||
}
|
||||
}
|
||||
|
||||
if (!Eflag) {
|
||||
update = options_get_string(&s->options,
|
||||
update = options_get_string(s->options,
|
||||
"update-environment");
|
||||
environ_update(update, &c->environ, &s->environ);
|
||||
environ_update(update, c->environ, s->environ);
|
||||
}
|
||||
|
||||
c->session = s;
|
||||
server_client_set_key_table(c, NULL);
|
||||
status_timer_start(c);
|
||||
notify_attached_session_changed(c);
|
||||
session_update_activity(s, NULL);
|
||||
|
|
@ -150,17 +120,21 @@ cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int dflag, int rflag,
|
|||
c->flags |= CLIENT_READONLY;
|
||||
|
||||
if (dflag) {
|
||||
server_write_session(s, MSG_DETACH, s->name,
|
||||
strlen(s->name) + 1);
|
||||
TAILQ_FOREACH(c_loop, &clients, entry) {
|
||||
if (c_loop->session != s || c == c_loop)
|
||||
continue;
|
||||
server_client_detach(c_loop, MSG_DETACH);
|
||||
}
|
||||
}
|
||||
|
||||
if (!Eflag) {
|
||||
update = options_get_string(&s->options,
|
||||
update = options_get_string(s->options,
|
||||
"update-environment");
|
||||
environ_update(update, &c->environ, &s->environ);
|
||||
environ_update(update, c->environ, s->environ);
|
||||
}
|
||||
|
||||
c->session = s;
|
||||
server_client_set_key_table(c, NULL);
|
||||
status_timer_start(c);
|
||||
notify_attached_session_changed(c);
|
||||
session_update_activity(s, NULL);
|
||||
|
|
@ -168,10 +142,13 @@ cmd_attach_session(struct cmd_q *cmdq, const char *tflag, int dflag, int rflag,
|
|||
server_redraw_client(c);
|
||||
s->curw->flags &= ~WINLINK_ALERTFLAGS;
|
||||
|
||||
server_write_ready(c);
|
||||
if (~c->flags & CLIENT_CONTROL)
|
||||
proc_send(c->peer, MSG_READY, -1, NULL, 0);
|
||||
hooks_run(c->session->hooks, c, NULL, "client-attached");
|
||||
cmdq->client_exit = 0;
|
||||
}
|
||||
recalculate_sizes();
|
||||
alerts_check_session(s);
|
||||
server_update_socket();
|
||||
|
||||
return (CMD_RETURN_NORMAL);
|
||||
|
|
@ -182,7 +159,6 @@ cmd_attach_session_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
{
|
||||
struct args *args = self->args;
|
||||
|
||||
return (cmd_attach_session(cmdq, args_get(args, 't'),
|
||||
args_has(args, 'd'), args_has(args, 'r'), args_get(args, 'c'),
|
||||
args_has(args, 'E')));
|
||||
return (cmd_attach_session(cmdq, args_has(args, 'd'),
|
||||
args_has(args, 'r'), args_get(args, 'c'), args_has(args, 'E')));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -29,14 +29,19 @@
|
|||
|
||||
enum cmd_retval cmd_bind_key_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
enum cmd_retval cmd_bind_key_mode_table(struct cmd *, struct cmd_q *, int);
|
||||
enum cmd_retval cmd_bind_key_mode_table(struct cmd *, struct cmd_q *,
|
||||
key_code);
|
||||
|
||||
const struct cmd_entry cmd_bind_key_entry = {
|
||||
"bind-key", "bind",
|
||||
"cnrt:T:", 1, -1,
|
||||
"[-cnr] [-t mode-table] [-T key-table] key command [arguments]",
|
||||
0,
|
||||
cmd_bind_key_exec
|
||||
.name = "bind-key",
|
||||
.alias = "bind",
|
||||
|
||||
.args = { "cnrt:T:", 1, -1 },
|
||||
.usage = "[-cnr] [-t mode-table] [-T key-table] key command "
|
||||
"[arguments]",
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_bind_key_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
|
|
@ -45,7 +50,7 @@ cmd_bind_key_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
struct args *args = self->args;
|
||||
char *cause;
|
||||
struct cmd_list *cmdlist;
|
||||
int key;
|
||||
key_code key;
|
||||
const char *tablename;
|
||||
|
||||
if (args_has(args, 't')) {
|
||||
|
|
@ -61,7 +66,7 @@ cmd_bind_key_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
}
|
||||
|
||||
key = key_string_lookup_string(args->argv[0]);
|
||||
if (key == KEYC_NONE) {
|
||||
if (key == KEYC_NONE || key == KEYC_UNKNOWN) {
|
||||
cmdq_error(cmdq, "unknown key: %s", args->argv[0]);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
|
@ -89,7 +94,7 @@ cmd_bind_key_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
}
|
||||
|
||||
enum cmd_retval
|
||||
cmd_bind_key_mode_table(struct cmd *self, struct cmd_q *cmdq, int key)
|
||||
cmd_bind_key_mode_table(struct cmd *self, struct cmd_q *cmdq, key_code key)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
const char *tablename;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -31,39 +31,43 @@
|
|||
enum cmd_retval cmd_break_pane_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_break_pane_entry = {
|
||||
"break-pane", "breakp",
|
||||
"dPF:s:t:", 0, 0,
|
||||
"[-dP] [-F format] " CMD_SRCDST_PANE_USAGE,
|
||||
0,
|
||||
cmd_break_pane_exec
|
||||
.name = "break-pane",
|
||||
.alias = "breakp",
|
||||
|
||||
.args = { "dPF:s:t:", 0, 0 },
|
||||
.usage = "[-dP] [-F format] [-s src-pane] [-t dst-window]",
|
||||
|
||||
.sflag = CMD_PANE,
|
||||
.tflag = CMD_WINDOW_INDEX,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_break_pane_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_break_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
#ifdef TMATE
|
||||
cmdq_error(cmdq, "break pane is not supported with tmate");
|
||||
return (CMD_RETURN_ERROR);
|
||||
#else
|
||||
struct args *args = self->args;
|
||||
struct winlink *wl;
|
||||
struct session *src_s;
|
||||
struct session *dst_s;
|
||||
struct window_pane *wp;
|
||||
struct window *w;
|
||||
struct winlink *wl = cmdq->state.sflag.wl;
|
||||
struct session *src_s = cmdq->state.sflag.s;
|
||||
struct session *dst_s = cmdq->state.tflag.s;
|
||||
struct window_pane *wp = cmdq->state.sflag.wp;
|
||||
struct window *w = wl->window;
|
||||
char *name;
|
||||
char *cause;
|
||||
int idx;
|
||||
int idx = cmdq->state.tflag.idx;
|
||||
struct format_tree *ft;
|
||||
const char *template;
|
||||
char *cp;
|
||||
|
||||
wl = cmd_find_pane(cmdq, args_get(args, 's'), &src_s, &wp);
|
||||
if (wl == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
if ((idx = cmd_find_index(cmdq, args_get(args, 't'), &dst_s)) == -2)
|
||||
return (CMD_RETURN_ERROR);
|
||||
if (idx != -1 && winlink_find_by_index(&dst_s->windows, idx) != NULL) {
|
||||
cmdq_error(cmdq, "index %d already in use", idx);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
w = wl->window;
|
||||
|
||||
if (window_count_panes(w) == 1) {
|
||||
cmdq_error(cmdq, "can't break with only one pane");
|
||||
|
|
@ -82,9 +86,10 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
window_set_name(w, name);
|
||||
free(name);
|
||||
layout_init(w, wp);
|
||||
wp->flags |= PANE_CHANGED;
|
||||
|
||||
if (idx == -1)
|
||||
idx = -1 - options_get_number(&dst_s->options, "base-index");
|
||||
idx = -1 - options_get_number(dst_s->options, "base-index");
|
||||
wl = session_attach(dst_s, w, idx, &cause); /* can't fail */
|
||||
if (!args_has(self->args, 'd'))
|
||||
session_select(dst_s, wl->idx);
|
||||
|
|
@ -100,9 +105,8 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
if ((template = args_get(args, 'F')) == NULL)
|
||||
template = BREAK_PANE_TEMPLATE;
|
||||
|
||||
ft = format_create();
|
||||
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), dst_s, wl,
|
||||
wp);
|
||||
ft = format_create(cmdq, 0);
|
||||
format_defaults(ft, cmdq->state.c, dst_s, wl, wp);
|
||||
|
||||
cp = format_expand(ft, template);
|
||||
cmdq_print(cmdq, "%s", cp);
|
||||
|
|
@ -111,4 +115,5 @@ cmd_break_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
format_free(ft);
|
||||
}
|
||||
return (CMD_RETURN_NORMAL);
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,12 +36,17 @@ char *cmd_capture_pane_history(struct args *, struct cmd_q *,
|
|||
struct window_pane *, size_t *);
|
||||
|
||||
const struct cmd_entry cmd_capture_pane_entry = {
|
||||
"capture-pane", "capturep",
|
||||
"ab:CeE:JpPqS:t:", 0, 0,
|
||||
"[-aCeJpPq] " CMD_BUFFER_USAGE " [-E end-line] [-S start-line]"
|
||||
CMD_TARGET_PANE_USAGE,
|
||||
0,
|
||||
cmd_capture_pane_exec
|
||||
.name = "capture-pane",
|
||||
.alias = "capturep",
|
||||
|
||||
.args = { "ab:CeE:JpPqS:t:", 0, 0 },
|
||||
.usage = "[-aCeJpPq] " CMD_BUFFER_USAGE " [-E end-line] "
|
||||
"[-S start-line]" CMD_TARGET_PANE_USAGE,
|
||||
|
||||
.tflag = CMD_PANE,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_capture_pane_exec
|
||||
};
|
||||
|
||||
char *
|
||||
|
|
@ -175,14 +180,11 @@ cmd_capture_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
{
|
||||
struct args *args = self->args;
|
||||
struct client *c;
|
||||
struct window_pane *wp;
|
||||
struct window_pane *wp = cmdq->state.tflag.wp;
|
||||
char *buf, *cause;
|
||||
const char *bufname;
|
||||
size_t len;
|
||||
|
||||
if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
||||
len = 0;
|
||||
if (args_has(args, 'P'))
|
||||
buf = cmd_capture_pane_pending(args, wp, &len);
|
||||
|
|
@ -203,7 +205,7 @@ cmd_capture_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
free(buf);
|
||||
if (args_has(args, 'P') && len > 0)
|
||||
evbuffer_add(c->stdout_data, "\n", 1);
|
||||
server_push_stdout(c);
|
||||
server_client_push_stdout(c);
|
||||
} else {
|
||||
bufname = NULL;
|
||||
if (args_has(args, 'b'))
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2010 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2010 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -33,27 +33,31 @@
|
|||
enum cmd_retval cmd_choose_buffer_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_choose_buffer_entry = {
|
||||
"choose-buffer", NULL,
|
||||
"F:t:", 0, 1,
|
||||
CMD_TARGET_WINDOW_USAGE " [-F format] [template]",
|
||||
0,
|
||||
cmd_choose_buffer_exec
|
||||
.name = "choose-buffer",
|
||||
.alias = NULL,
|
||||
|
||||
.args = { "F:t:", 0, 1 },
|
||||
.usage = CMD_TARGET_WINDOW_USAGE " [-F format] [template]",
|
||||
|
||||
.tflag = CMD_WINDOW,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_choose_buffer_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_choose_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct client *c;
|
||||
struct client *c = cmdq->state.c;
|
||||
struct winlink *wl = cmdq->state.tflag.wl;
|
||||
struct window_choose_data *cdata;
|
||||
struct winlink *wl;
|
||||
struct paste_buffer *pb;
|
||||
char *action, *action_data;
|
||||
const char *template;
|
||||
u_int idx;
|
||||
int utf8flag;
|
||||
|
||||
if ((c = cmd_find_client(cmdq, NULL, 1)) == NULL) {
|
||||
if (c == NULL) {
|
||||
cmdq_error(cmdq, "no client available");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
|
@ -61,10 +65,6 @@ cmd_choose_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
if ((template = args_get(args, 'F')) == NULL)
|
||||
template = CHOOSE_BUFFER_TEMPLATE;
|
||||
|
||||
if ((wl = cmd_find_window(cmdq, args_get(args, 't'), NULL)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
utf8flag = options_get_number(&wl->window->options, "utf8");
|
||||
|
||||
if (paste_get_top(NULL) == NULL)
|
||||
return (CMD_RETURN_NORMAL);
|
||||
|
||||
|
|
@ -83,7 +83,7 @@ cmd_choose_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
cdata->idx = idx;
|
||||
|
||||
cdata->ft_template = xstrdup(template);
|
||||
format_defaults_paste_buffer(cdata->ft, pb, utf8flag);
|
||||
format_defaults_paste_buffer(cdata->ft, pb);
|
||||
|
||||
xasprintf(&action_data, "%s", paste_buffer_name(pb));
|
||||
cdata->command = cmd_template_replace(action, action_data, 1);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -31,18 +31,23 @@
|
|||
"#{client_tty}: #{session_name} " \
|
||||
"[#{client_width}x#{client_height} #{client_termname}]" \
|
||||
"#{?client_utf8, (utf8),}#{?client_readonly, (ro),} " \
|
||||
"(last used #{client_activity_string})"
|
||||
"(last used #{t:client_activity})"
|
||||
|
||||
enum cmd_retval cmd_choose_client_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
void cmd_choose_client_callback(struct window_choose_data *);
|
||||
|
||||
const struct cmd_entry cmd_choose_client_entry = {
|
||||
"choose-client", NULL,
|
||||
"F:t:", 0, 1,
|
||||
CMD_TARGET_WINDOW_USAGE " [-F format] [template]",
|
||||
0,
|
||||
cmd_choose_client_exec
|
||||
.name = "choose-client",
|
||||
.alias = NULL,
|
||||
|
||||
.args = { "F:t:", 0, 1 },
|
||||
.usage = CMD_TARGET_WINDOW_USAGE " [-F format] [template]",
|
||||
|
||||
.tflag = CMD_WINDOW,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_choose_client_exec
|
||||
};
|
||||
|
||||
struct cmd_choose_client_data {
|
||||
|
|
@ -53,22 +58,19 @@ enum cmd_retval
|
|||
cmd_choose_client_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct client *c;
|
||||
struct client *c = cmdq->state.c;
|
||||
struct client *c1;
|
||||
struct window_choose_data *cdata;
|
||||
struct winlink *wl;
|
||||
struct winlink *wl = cmdq->state.tflag.wl;
|
||||
const char *template;
|
||||
char *action;
|
||||
u_int idx, cur;
|
||||
|
||||
if ((c = cmd_find_client(cmdq, NULL, 1)) == NULL) {
|
||||
if (c == NULL) {
|
||||
cmdq_error(cmdq, "no client available");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
if ((wl = cmd_find_window(cmdq, args_get(args, 't'), NULL)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
||||
if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
|
||||
return (CMD_RETURN_NORMAL);
|
||||
|
||||
|
|
|
|||
|
|
@ -44,37 +44,52 @@
|
|||
enum cmd_retval cmd_choose_tree_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_choose_tree_entry = {
|
||||
"choose-tree", NULL,
|
||||
"S:W:swub:c:t:", 0, 1,
|
||||
"[-suw] [-b session-template] [-c window template] [-S format] " \
|
||||
"[-W format] " CMD_TARGET_WINDOW_USAGE,
|
||||
0,
|
||||
cmd_choose_tree_exec
|
||||
.name = "choose-tree",
|
||||
.alias = NULL,
|
||||
|
||||
.args = { "S:W:swub:c:t:", 0, 1 },
|
||||
.usage = "[-suw] [-b session-template] [-c window template] "
|
||||
"[-S format] [-W format] " CMD_TARGET_WINDOW_USAGE,
|
||||
|
||||
.tflag = CMD_WINDOW,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_choose_tree_exec
|
||||
};
|
||||
|
||||
const struct cmd_entry cmd_choose_session_entry = {
|
||||
"choose-session", NULL,
|
||||
"F:t:", 0, 1,
|
||||
CMD_TARGET_WINDOW_USAGE " [-F format] [template]",
|
||||
0,
|
||||
cmd_choose_tree_exec
|
||||
.name = "choose-session",
|
||||
.alias = NULL,
|
||||
|
||||
.args = { "F:t:", 0, 1 },
|
||||
.usage = CMD_TARGET_WINDOW_USAGE " [-F format] [template]",
|
||||
|
||||
.tflag = CMD_WINDOW,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_choose_tree_exec
|
||||
};
|
||||
|
||||
const struct cmd_entry cmd_choose_window_entry = {
|
||||
"choose-window", NULL,
|
||||
"F:t:", 0, 1,
|
||||
CMD_TARGET_WINDOW_USAGE "[-F format] [template]",
|
||||
0,
|
||||
cmd_choose_tree_exec
|
||||
.name = "choose-window",
|
||||
.alias = NULL,
|
||||
|
||||
.args = { "F:t:", 0, 1 },
|
||||
.usage = CMD_TARGET_WINDOW_USAGE "[-F format] [template]",
|
||||
|
||||
.tflag = CMD_WINDOW,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_choose_tree_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_choose_tree_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct winlink *wl, *wm;
|
||||
struct session *s, *s2;
|
||||
struct client *c;
|
||||
struct client *c = cmdq->state.c;
|
||||
struct winlink *wl = cmdq->state.tflag.wl, *wm;
|
||||
struct session *s = cmdq->state.tflag.s, *s2;
|
||||
struct window_choose_data *wcd = NULL;
|
||||
const char *ses_template, *win_template;
|
||||
char *final_win_action, *cur_win_template;
|
||||
|
|
@ -87,14 +102,11 @@ cmd_choose_tree_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
ses_template = win_template = NULL;
|
||||
ses_action = win_action = NULL;
|
||||
|
||||
if ((c = cmd_find_client(cmdq, NULL, 1)) == NULL) {
|
||||
if (c == NULL) {
|
||||
cmdq_error(cmdq, "no client available");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
if ((wl = cmd_find_window(cmdq, args_get(args, 't'), &s)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
||||
if (window_pane_set_mode(wl->window->active, &window_choose_mode) != 0)
|
||||
return (CMD_RETURN_NORMAL);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -27,23 +27,25 @@
|
|||
enum cmd_retval cmd_clear_history_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_clear_history_entry = {
|
||||
"clear-history", "clearhist",
|
||||
"t:", 0, 0,
|
||||
CMD_TARGET_PANE_USAGE,
|
||||
0,
|
||||
cmd_clear_history_exec
|
||||
.name = "clear-history",
|
||||
.alias = "clearhist",
|
||||
|
||||
.args = { "t:", 0, 0 },
|
||||
.usage = CMD_TARGET_PANE_USAGE,
|
||||
|
||||
.tflag = CMD_PANE,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_clear_history_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_clear_history_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
cmd_clear_history_exec(__unused struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct window_pane *wp;
|
||||
struct window_pane *wp = cmdq->state.tflag.wp;
|
||||
struct grid *gd;
|
||||
|
||||
if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
gd = wp->base.grid;
|
||||
gd = cmdq->state.tflag.wp->base.grid;
|
||||
|
||||
if (wp->mode == &window_copy_mode)
|
||||
window_pane_reset_mode(wp);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -35,11 +35,17 @@ int cmd_command_prompt_callback(void *, const char *);
|
|||
void cmd_command_prompt_free(void *);
|
||||
|
||||
const struct cmd_entry cmd_command_prompt_entry = {
|
||||
"command-prompt", NULL,
|
||||
"I:p:t:", 0, 1,
|
||||
"[-I inputs] [-p prompts] " CMD_TARGET_CLIENT_USAGE " [template]",
|
||||
0,
|
||||
cmd_command_prompt_exec
|
||||
.name = "command-prompt",
|
||||
.alias = NULL,
|
||||
|
||||
.args = { "I:p:t:", 0, 1 },
|
||||
.usage = "[-I inputs] [-p prompts] " CMD_TARGET_CLIENT_USAGE " "
|
||||
"[template]",
|
||||
|
||||
.tflag = CMD_CLIENT,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_command_prompt_exec
|
||||
};
|
||||
|
||||
struct cmd_command_prompt_cdata {
|
||||
|
|
@ -58,13 +64,10 @@ cmd_command_prompt_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
struct args *args = self->args;
|
||||
const char *inputs, *prompts;
|
||||
struct cmd_command_prompt_cdata *cdata;
|
||||
struct client *c;
|
||||
struct client *c = cmdq->state.c;
|
||||
char *prompt, *ptr, *input = NULL;
|
||||
size_t n;
|
||||
|
||||
if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
||||
if (c->prompt_string != NULL)
|
||||
return (CMD_RETURN_NORMAL);
|
||||
|
||||
|
|
|
|||
|
|
@ -34,11 +34,16 @@ int cmd_confirm_before_callback(void *, const char *);
|
|||
void cmd_confirm_before_free(void *);
|
||||
|
||||
const struct cmd_entry cmd_confirm_before_entry = {
|
||||
"confirm-before", "confirm",
|
||||
"p:t:", 1, 1,
|
||||
"[-p prompt] " CMD_TARGET_CLIENT_USAGE " command",
|
||||
0,
|
||||
cmd_confirm_before_exec
|
||||
.name = "confirm-before",
|
||||
.alias = "confirm",
|
||||
|
||||
.args = { "p:t:", 1, 1 },
|
||||
.usage = "[-p prompt] " CMD_TARGET_CLIENT_USAGE " command",
|
||||
|
||||
.tflag = CMD_CLIENT,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_confirm_before_exec
|
||||
};
|
||||
|
||||
struct cmd_confirm_before_data {
|
||||
|
|
@ -51,13 +56,10 @@ cmd_confirm_before_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
{
|
||||
struct args *args = self->args;
|
||||
struct cmd_confirm_before_data *cdata;
|
||||
struct client *c;
|
||||
struct client *c = cmdq->state.c;
|
||||
char *cmd, *copy, *new_prompt, *ptr;
|
||||
const char *prompt;
|
||||
|
||||
if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
||||
if ((prompt = args_get(args, 'p')) != NULL)
|
||||
xasprintf(&new_prompt, "%s ", prompt);
|
||||
else {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -27,19 +27,29 @@
|
|||
enum cmd_retval cmd_copy_mode_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_copy_mode_entry = {
|
||||
"copy-mode", NULL,
|
||||
"Met:u", 0, 0,
|
||||
"[-Meu] " CMD_TARGET_PANE_USAGE,
|
||||
0,
|
||||
cmd_copy_mode_exec
|
||||
.name = "copy-mode",
|
||||
.alias = NULL,
|
||||
|
||||
.args = { "Met:u", 0, 0 },
|
||||
.usage = "[-Mu] " CMD_TARGET_PANE_USAGE,
|
||||
|
||||
.tflag = CMD_PANE,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_copy_mode_exec
|
||||
};
|
||||
|
||||
const struct cmd_entry cmd_clock_mode_entry = {
|
||||
"clock-mode", NULL,
|
||||
"t:", 0, 0,
|
||||
CMD_TARGET_PANE_USAGE,
|
||||
0,
|
||||
cmd_copy_mode_exec
|
||||
.name = "clock-mode",
|
||||
.alias = NULL,
|
||||
|
||||
.args = { "t:", 0, 0 },
|
||||
.usage = CMD_TARGET_PANE_USAGE,
|
||||
|
||||
.tflag = CMD_PANE,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_copy_mode_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
|
|
@ -48,15 +58,14 @@ cmd_copy_mode_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
struct args *args = self->args;
|
||||
struct client *c = cmdq->client;
|
||||
struct session *s;
|
||||
struct window_pane *wp;
|
||||
struct window_pane *wp = cmdq->state.tflag.wp;
|
||||
|
||||
if (args_has(args, 'M')) {
|
||||
if ((wp = cmd_mouse_pane(&cmdq->item->mouse, &s, NULL)) == NULL)
|
||||
return (CMD_RETURN_NORMAL);
|
||||
if (c == NULL || c->session != s)
|
||||
return (CMD_RETURN_NORMAL);
|
||||
} else if (cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
if (self->entry == &cmd_clock_mode_entry) {
|
||||
window_pane_set_mode(wp, &window_clock_mode);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -29,35 +29,44 @@
|
|||
enum cmd_retval cmd_detach_client_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_detach_client_entry = {
|
||||
"detach-client", "detach",
|
||||
"as:t:P", 0, 0,
|
||||
"[-P] [-a] [-s target-session] " CMD_TARGET_CLIENT_USAGE,
|
||||
CMD_READONLY,
|
||||
cmd_detach_client_exec
|
||||
.name = "detach-client",
|
||||
.alias = "detach",
|
||||
|
||||
.args = { "as:t:P", 0, 0 },
|
||||
.usage = "[-P] [-a] [-s target-session] " CMD_TARGET_CLIENT_USAGE,
|
||||
|
||||
.sflag = CMD_SESSION,
|
||||
.tflag = CMD_CLIENT,
|
||||
|
||||
.flags = CMD_READONLY,
|
||||
.exec = cmd_detach_client_exec
|
||||
};
|
||||
|
||||
const struct cmd_entry cmd_suspend_client_entry = {
|
||||
"suspend-client", "suspendc",
|
||||
"t:", 0, 0,
|
||||
CMD_TARGET_CLIENT_USAGE,
|
||||
0,
|
||||
cmd_detach_client_exec
|
||||
.name = "suspend-client",
|
||||
.alias = "suspendc",
|
||||
|
||||
.args = { "t:", 0, 0 },
|
||||
.usage = CMD_TARGET_CLIENT_USAGE,
|
||||
|
||||
.tflag = CMD_CLIENT,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_detach_client_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_detach_client_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct client *c, *cloop;
|
||||
struct client *c = cmdq->state.c, *cloop;
|
||||
struct session *s;
|
||||
enum msgtype msgtype;
|
||||
|
||||
if (self->entry == &cmd_suspend_client_entry) {
|
||||
if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
tty_stop_tty(&c->tty);
|
||||
c->flags |= CLIENT_SUSPENDED;
|
||||
server_write_client(c, MSG_SUSPEND, NULL, 0);
|
||||
proc_send(c->peer, MSG_SUSPEND, -1, NULL, 0);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
|
|
@ -67,36 +76,22 @@ cmd_detach_client_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
msgtype = MSG_DETACH;
|
||||
|
||||
if (args_has(args, 's')) {
|
||||
s = cmd_find_session(cmdq, args_get(args, 's'), 0);
|
||||
if (s == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
||||
s = cmdq->state.sflag.s;
|
||||
TAILQ_FOREACH(cloop, &clients, entry) {
|
||||
if (cloop->session != s)
|
||||
continue;
|
||||
server_write_client(cloop, msgtype,
|
||||
cloop->session->name,
|
||||
strlen(cloop->session->name) + 1);
|
||||
if (cloop->session == s)
|
||||
server_client_detach(cloop, msgtype);
|
||||
}
|
||||
return (CMD_RETURN_STOP);
|
||||
}
|
||||
|
||||
c = cmd_find_client(cmdq, args_get(args, 't'), 0);
|
||||
if (c == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
||||
if (args_has(args, 'a')) {
|
||||
TAILQ_FOREACH(cloop, &clients, entry) {
|
||||
if (cloop->session == NULL || cloop == c)
|
||||
continue;
|
||||
server_write_client(cloop, msgtype,
|
||||
cloop->session->name,
|
||||
strlen(cloop->session->name) + 1);
|
||||
if (cloop->session != NULL && cloop != c)
|
||||
server_client_detach(cloop, msgtype);
|
||||
}
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
server_write_client(c, msgtype, c->session->name,
|
||||
strlen(c->session->name) + 1);
|
||||
server_client_detach(c, msgtype);
|
||||
return (CMD_RETURN_STOP);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,70 +35,47 @@
|
|||
enum cmd_retval cmd_display_message_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_display_message_entry = {
|
||||
"display-message", "display",
|
||||
"c:pt:F:", 0, 1,
|
||||
"[-p] [-c target-client] [-F format] " CMD_TARGET_PANE_USAGE
|
||||
" [message]",
|
||||
0,
|
||||
cmd_display_message_exec
|
||||
.name = "display-message",
|
||||
.alias = "display",
|
||||
|
||||
.args = { "c:pt:F:", 0, 1 },
|
||||
.usage = "[-p] [-c target-client] [-F format] "
|
||||
CMD_TARGET_PANE_USAGE " [message]",
|
||||
|
||||
.cflag = CMD_CLIENT_CANFAIL,
|
||||
.tflag = CMD_PANE,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_display_message_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_display_message_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct client *c;
|
||||
struct session *s;
|
||||
struct winlink *wl;
|
||||
struct window_pane *wp;
|
||||
struct client *c = cmdq->state.c;
|
||||
struct session *s = cmdq->state.tflag.s;
|
||||
struct winlink *wl = cmdq->state.tflag.wl;
|
||||
struct window_pane *wp = cmdq->state.tflag.wp;
|
||||
const char *template;
|
||||
char *msg;
|
||||
struct format_tree *ft;
|
||||
char out[BUFSIZ];
|
||||
time_t t;
|
||||
size_t len;
|
||||
|
||||
if (args_has(args, 't')) {
|
||||
wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp);
|
||||
if (wl == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
} else {
|
||||
wl = cmd_find_pane(cmdq, NULL, &s, &wp);
|
||||
if (wl == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
if (args_has(args, 'F') && args->argc != 0) {
|
||||
cmdq_error(cmdq, "only one of -F or argument must be given");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
if (args_has(args, 'c')) {
|
||||
c = cmd_find_client(cmdq, args_get(args, 'c'), 0);
|
||||
if (c == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
} else {
|
||||
c = cmd_find_client(cmdq, NULL, 1);
|
||||
if (c == NULL && !args_has(self->args, 'p')) {
|
||||
cmdq_error(cmdq, "no client available");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
template = args_get(args, 'F');
|
||||
if (args->argc != 0)
|
||||
template = args->argv[0];
|
||||
if (template == NULL)
|
||||
template = DISPLAY_MESSAGE_TEMPLATE;
|
||||
|
||||
ft = format_create();
|
||||
ft = format_create(cmdq, 0);
|
||||
format_defaults(ft, c, s, wl, wp);
|
||||
|
||||
t = time(NULL);
|
||||
len = strftime(out, sizeof out, template, localtime(&t));
|
||||
out[len] = '\0';
|
||||
|
||||
msg = format_expand(ft, out);
|
||||
msg = format_expand_time(ft, template, time(NULL));
|
||||
if (args_has(self->args, 'p'))
|
||||
cmdq_print(cmdq, "%s", msg);
|
||||
else
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -27,23 +27,22 @@
|
|||
enum cmd_retval cmd_display_panes_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_display_panes_entry = {
|
||||
"display-panes", "displayp",
|
||||
"t:", 0, 0,
|
||||
CMD_TARGET_CLIENT_USAGE,
|
||||
0,
|
||||
cmd_display_panes_exec
|
||||
.name = "display-panes",
|
||||
.alias = "displayp",
|
||||
|
||||
.args = { "t:", 0, 0 },
|
||||
.usage = CMD_TARGET_CLIENT_USAGE,
|
||||
|
||||
.tflag = CMD_CLIENT,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_display_panes_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_display_panes_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
cmd_display_panes_exec(__unused struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct client *c;
|
||||
|
||||
if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
||||
server_set_identify(c);
|
||||
server_set_identify(cmdq->state.c);
|
||||
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -48,11 +48,16 @@ void cmd_find_window_callback(struct window_choose_data *);
|
|||
CMD_FIND_WINDOW_BY_NAME)
|
||||
|
||||
const struct cmd_entry cmd_find_window_entry = {
|
||||
"find-window", "findw",
|
||||
"F:CNt:T", 1, 4,
|
||||
"[-CNT] [-F format] " CMD_TARGET_WINDOW_USAGE " match-string",
|
||||
0,
|
||||
cmd_find_window_exec
|
||||
.name = "find-window",
|
||||
.alias = "findw",
|
||||
|
||||
.args = { "F:CNt:T", 1, 4 },
|
||||
.usage = "[-CNT] [-F format] " CMD_TARGET_WINDOW_USAGE " match-string",
|
||||
|
||||
.tflag = CMD_WINDOW,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_find_window_exec
|
||||
};
|
||||
|
||||
struct cmd_find_window_data {
|
||||
|
|
@ -137,10 +142,10 @@ enum cmd_retval
|
|||
cmd_find_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct client *c;
|
||||
struct client *c = cmdq->state.c;
|
||||
struct window_choose_data *cdata;
|
||||
struct session *s;
|
||||
struct winlink *wl, *wm;
|
||||
struct session *s = cmdq->state.tflag.s;
|
||||
struct winlink *wl = cmdq->state.tflag.wl, *wm;
|
||||
struct cmd_find_window_list find_list;
|
||||
struct cmd_find_window_data *find_data;
|
||||
struct cmd_find_window_data *find_data1;
|
||||
|
|
@ -148,14 +153,10 @@ cmd_find_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
const char *template;
|
||||
u_int i, match_flags;
|
||||
|
||||
if ((c = cmd_find_client(cmdq, NULL, 1)) == NULL) {
|
||||
if (c == NULL) {
|
||||
cmdq_error(cmdq, "no client available");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
s = c->session;
|
||||
|
||||
if ((wl = cmd_find_window(cmdq, args_get(args, 't'), NULL)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
||||
if ((template = args_get(args, 'F')) == NULL)
|
||||
template = FIND_WINDOW_TEMPLATE;
|
||||
|
|
|
|||
569
cmd-find.c
569
cmd-find.c
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2015 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2015 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -22,34 +22,11 @@
|
|||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "tmux.h"
|
||||
|
||||
#define CMD_FIND_PREFER_UNATTACHED 0x1
|
||||
#define CMD_FIND_QUIET 0x2
|
||||
#define CMD_FIND_WINDOW_INDEX 0x4
|
||||
#define CMD_FIND_DEFAULT_MARKED 0x8
|
||||
#define CMD_FIND_EXACT_SESSION 0x10
|
||||
#define CMD_FIND_EXACT_WINDOW 0x20
|
||||
|
||||
enum cmd_find_type {
|
||||
CMD_FIND_PANE,
|
||||
CMD_FIND_WINDOW,
|
||||
CMD_FIND_SESSION,
|
||||
};
|
||||
|
||||
struct cmd_find_state {
|
||||
struct cmd_q *cmdq;
|
||||
int flags;
|
||||
struct cmd_find_state *current;
|
||||
|
||||
struct session *s;
|
||||
struct winlink *wl;
|
||||
struct window *w;
|
||||
struct window_pane *wp;
|
||||
int idx;
|
||||
};
|
||||
|
||||
struct session *cmd_find_try_TMUX(struct client *, struct window *);
|
||||
int cmd_find_client_better(struct client *, struct client *);
|
||||
struct client *cmd_find_best_client(struct client **, u_int);
|
||||
int cmd_find_session_better(struct session *, struct session *,
|
||||
|
|
@ -72,12 +49,6 @@ int cmd_find_get_pane(struct cmd_find_state *, const char *);
|
|||
int cmd_find_get_pane_with_session(struct cmd_find_state *, const char *);
|
||||
int cmd_find_get_pane_with_window(struct cmd_find_state *, const char *);
|
||||
|
||||
void cmd_find_clear_state(struct cmd_find_state *, struct cmd_q *, int);
|
||||
void cmd_find_log_state(const char *, const char *, struct cmd_find_state *);
|
||||
|
||||
struct cmd_find_state *cmd_find_target(struct cmd_q *, const char *,
|
||||
enum cmd_find_type, int);
|
||||
|
||||
const char *cmd_find_session_table[][2] = {
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
|
@ -108,6 +79,33 @@ const char *cmd_find_pane_table[][2] = {
|
|||
{ NULL, NULL }
|
||||
};
|
||||
|
||||
/* Get session from TMUX if present. */
|
||||
struct session *
|
||||
cmd_find_try_TMUX(struct client *c, struct window *w)
|
||||
{
|
||||
struct environ_entry *envent;
|
||||
char tmp[256];
|
||||
long long pid;
|
||||
u_int session;
|
||||
struct session *s;
|
||||
|
||||
envent = environ_find(c->environ, "TMUX");
|
||||
if (envent == NULL)
|
||||
return (NULL);
|
||||
|
||||
if (sscanf(envent->value, "%255[^,],%lld,%d", tmp, &pid, &session) != 3)
|
||||
return (NULL);
|
||||
if (pid != getpid())
|
||||
return (NULL);
|
||||
log_debug("client %p TMUX is %s (session @%u)", c, envent->value,
|
||||
session);
|
||||
|
||||
s = session_find_by_id(session);
|
||||
if (s == NULL || (w != NULL && !session_has(s, w)))
|
||||
return (NULL);
|
||||
return (s);
|
||||
}
|
||||
|
||||
/* Is this client better? */
|
||||
int
|
||||
cmd_find_client_better(struct client *c, struct client *than)
|
||||
|
|
@ -191,6 +189,12 @@ cmd_find_best_session_with_window(struct cmd_find_state *fs)
|
|||
u_int ssize;
|
||||
struct session *s;
|
||||
|
||||
if (fs->cmdq != NULL && fs->cmdq->client != NULL) {
|
||||
fs->s = cmd_find_try_TMUX(fs->cmdq->client, fs->w);
|
||||
if (fs->s != NULL)
|
||||
return (cmd_find_best_winlink_with_window(fs));
|
||||
}
|
||||
|
||||
ssize = 0;
|
||||
RB_FOREACH(s, sessions, &sessions) {
|
||||
if (!session_has(s, fs->w))
|
||||
|
|
@ -244,8 +248,12 @@ cmd_find_current_session_with_client(struct cmd_find_state *fs)
|
|||
{
|
||||
struct window_pane *wp;
|
||||
|
||||
/* If this is running in a pane, that's great. */
|
||||
if (fs->cmdq->client->tty.path != NULL) {
|
||||
/*
|
||||
* If this is running in a pane, we can use that to limit the list of
|
||||
* sessions to those containing that pane (we still use the current
|
||||
* window in the best session).
|
||||
*/
|
||||
if (fs->cmdq != NULL && fs->cmdq->client->tty.path != NULL) {
|
||||
RB_FOREACH(wp, window_pane_tree, &all_window_panes) {
|
||||
if (strcmp(wp->tty, fs->cmdq->client->tty.path) == 0)
|
||||
break;
|
||||
|
|
@ -254,24 +262,44 @@ cmd_find_current_session_with_client(struct cmd_find_state *fs)
|
|||
wp = NULL;
|
||||
|
||||
/* Not running in a pane. We know nothing. Find the best session. */
|
||||
if (wp == NULL) {
|
||||
fs->s = cmd_find_best_session(NULL, 0, fs->flags);
|
||||
if (fs->s == NULL)
|
||||
return (-1);
|
||||
fs->wl = fs->s->curw;
|
||||
fs->idx = fs->wl->idx;
|
||||
fs->w = fs->wl->window;
|
||||
fs->wp = fs->w->active;
|
||||
return (0);
|
||||
if (wp == NULL)
|
||||
goto unknown_pane;
|
||||
|
||||
/* Find the best session and winlink containing this pane. */
|
||||
fs->w = wp->window;
|
||||
if (cmd_find_best_session_with_window(fs) != 0) {
|
||||
if (wp != NULL) {
|
||||
/*
|
||||
* The window may have been destroyed but the pane
|
||||
* still on all_window_panes due to something else
|
||||
* holding a reference.
|
||||
*/
|
||||
goto unknown_pane;
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* We now know the window and pane. */
|
||||
fs->w = wp->window;
|
||||
fs->wp = wp;
|
||||
/* Use the current window and pane from this session. */
|
||||
fs->wl = fs->s->curw;
|
||||
fs->idx = fs->wl->idx;
|
||||
fs->w = fs->wl->window;
|
||||
fs->wp = fs->w->active;
|
||||
|
||||
/* Find the best session and winlink. */
|
||||
if (cmd_find_best_session_with_window(fs) != 0)
|
||||
return (0);
|
||||
|
||||
unknown_pane:
|
||||
fs->s = NULL;
|
||||
if (fs->cmdq != NULL)
|
||||
fs->s = cmd_find_try_TMUX(fs->cmdq->client, NULL);
|
||||
if (fs->s == NULL)
|
||||
fs->s = cmd_find_best_session(NULL, 0, fs->flags);
|
||||
if (fs->s == NULL)
|
||||
return (-1);
|
||||
fs->wl = fs->s->curw;
|
||||
fs->idx = fs->wl->idx;
|
||||
fs->w = fs->wl->window;
|
||||
fs->wp = fs->w->active;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
|
@ -283,7 +311,9 @@ int
|
|||
cmd_find_current_session(struct cmd_find_state *fs)
|
||||
{
|
||||
/* If we know the current client, use it. */
|
||||
if (fs->cmdq->client != NULL) {
|
||||
if (fs->cmdq != NULL && fs->cmdq->client != NULL) {
|
||||
log_debug("%s: have client %p%s", __func__, fs->cmdq->client,
|
||||
fs->cmdq->client->session == NULL ? "" : " (with session)");
|
||||
if (fs->cmdq->client->session == NULL)
|
||||
return (cmd_find_current_session_with_client(fs));
|
||||
fs->s = fs->cmdq->client->session;
|
||||
|
|
@ -316,8 +346,11 @@ cmd_find_current_client(struct cmd_q *cmdq)
|
|||
u_int csize;
|
||||
|
||||
/* If the queue client has a session, use it. */
|
||||
if (cmdq->client != NULL && cmdq->client->session != NULL)
|
||||
if (cmdq->client != NULL && cmdq->client->session != NULL) {
|
||||
log_debug("%s: using cmdq %p client %p", __func__, cmdq,
|
||||
cmdq->client);
|
||||
return (cmdq->client);
|
||||
}
|
||||
|
||||
/* Otherwise find the current session. */
|
||||
cmd_find_clear_state(¤t, cmdq, 0);
|
||||
|
|
@ -326,6 +359,7 @@ cmd_find_current_client(struct cmd_q *cmdq)
|
|||
|
||||
/* If it is attached, find the best of it's clients. */
|
||||
s = current.s;
|
||||
log_debug("%s: current session $%u %s", __func__, s->id, s->name);
|
||||
if (~s->flags & SESSION_UNATTACHED) {
|
||||
csize = 0;
|
||||
TAILQ_FOREACH(c, &clients, entry) {
|
||||
|
|
@ -366,6 +400,7 @@ int
|
|||
cmd_find_get_session(struct cmd_find_state *fs, const char *session)
|
||||
{
|
||||
struct session *s, *s_loop;
|
||||
struct client *c;
|
||||
|
||||
log_debug("%s: %s", __func__, session);
|
||||
|
||||
|
|
@ -382,6 +417,13 @@ cmd_find_get_session(struct cmd_find_state *fs, const char *session)
|
|||
if (fs->s != NULL)
|
||||
return (0);
|
||||
|
||||
/* Look for as a client. */
|
||||
c = cmd_find_client(NULL, session, 1);
|
||||
if (c != NULL && c->session != NULL) {
|
||||
fs->s = c->session;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Stop now if exact only. */
|
||||
if (fs->flags & CMD_FIND_EXACT_SESSION)
|
||||
return (-1);
|
||||
|
|
@ -440,11 +482,10 @@ cmd_find_get_window(struct cmd_find_state *fs, const char *window)
|
|||
|
||||
/* Otherwise try as a session itself. */
|
||||
if (cmd_find_get_session(fs, window) == 0) {
|
||||
if (~fs->flags & CMD_FIND_WINDOW_INDEX) {
|
||||
fs->wl = fs->s->curw;
|
||||
fs->w = fs->wl->window;
|
||||
fs->wl = fs->s->curw;
|
||||
fs->w = fs->wl->window;
|
||||
if (~fs->flags & CMD_FIND_WINDOW_INDEX)
|
||||
fs->idx = fs->wl->idx;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
|
@ -466,6 +507,13 @@ cmd_find_get_window_with_session(struct cmd_find_state *fs, const char *window)
|
|||
log_debug("%s: %s", __func__, window);
|
||||
exact = (fs->flags & CMD_FIND_EXACT_WINDOW);
|
||||
|
||||
/*
|
||||
* Start with the current window as the default. So if only an index is
|
||||
* found, the window will be the current.
|
||||
*/
|
||||
fs->wl = fs->s->curw;
|
||||
fs->w = fs->wl->window;
|
||||
|
||||
/* Check for window ids starting with @. */
|
||||
if (*window == '@') {
|
||||
fs->w = window_find_by_id_str(window);
|
||||
|
|
@ -762,34 +810,168 @@ cmd_find_clear_state(struct cmd_find_state *fs, struct cmd_q *cmdq, int flags)
|
|||
fs->idx = -1;
|
||||
}
|
||||
|
||||
/* Split target into pieces and resolve for the given type. */
|
||||
struct cmd_find_state *
|
||||
cmd_find_target(struct cmd_q *cmdq, const char *target, enum cmd_find_type type,
|
||||
int flags)
|
||||
/* Check if a state if valid. */
|
||||
int
|
||||
cmd_find_valid_state(struct cmd_find_state *fs)
|
||||
{
|
||||
static struct cmd_find_state fs, current;
|
||||
struct mouse_event *m;
|
||||
char *colon, *period, *copy = NULL;
|
||||
const char *session, *window, *pane;
|
||||
struct winlink *wl;
|
||||
|
||||
/* Find current state. */
|
||||
cmd_find_clear_state(¤t, cmdq, flags);
|
||||
if (server_check_marked() && (flags & CMD_FIND_DEFAULT_MARKED)) {
|
||||
current.s = marked_session;
|
||||
current.wl = marked_winlink;
|
||||
current.idx = current.wl->idx;
|
||||
current.w = current.wl->window;
|
||||
current.wp = marked_window_pane;
|
||||
if (fs->s == NULL || fs->wl == NULL || fs->w == NULL || fs->wp == NULL)
|
||||
return (0);
|
||||
|
||||
if (!session_alive(fs->s))
|
||||
return (0);
|
||||
|
||||
RB_FOREACH(wl, winlinks, &fs->s->windows) {
|
||||
if (wl->window == fs->w && wl == fs->wl)
|
||||
break;
|
||||
}
|
||||
if (current.s == NULL && cmd_find_current_session(¤t) != 0) {
|
||||
if (wl == NULL)
|
||||
return (0);
|
||||
|
||||
if (fs->w != fs->wl->window)
|
||||
return (0);
|
||||
|
||||
if (!window_has_pane(fs->w, fs->wp))
|
||||
return (0);
|
||||
return (window_pane_visible(fs->wp));
|
||||
}
|
||||
|
||||
/* Copy a state. */
|
||||
void
|
||||
cmd_find_copy_state(struct cmd_find_state *dst, struct cmd_find_state *src)
|
||||
{
|
||||
dst->s = src->s;
|
||||
dst->wl = src->wl;
|
||||
dst->idx = src->idx;
|
||||
dst->w = src->w;
|
||||
dst->wp = src->wp;
|
||||
}
|
||||
|
||||
/* Log the result. */
|
||||
void
|
||||
cmd_find_log_state(const char *prefix, struct cmd_find_state *fs)
|
||||
{
|
||||
if (fs->s != NULL)
|
||||
log_debug("%s: s=$%u", prefix, fs->s->id);
|
||||
else
|
||||
log_debug("%s: s=none", prefix);
|
||||
if (fs->wl != NULL) {
|
||||
log_debug("%s: wl=%u %d w=@%u %s", prefix, fs->wl->idx,
|
||||
fs->wl->window == fs->w, fs->w->id, fs->w->name);
|
||||
} else
|
||||
log_debug("%s: wl=none", prefix);
|
||||
if (fs->wp != NULL)
|
||||
log_debug("%s: wp=%%%u", prefix, fs->wp->id);
|
||||
else
|
||||
log_debug("%s: wp=none", prefix);
|
||||
if (fs->idx != -1)
|
||||
log_debug("%s: idx=%d", prefix, fs->idx);
|
||||
else
|
||||
log_debug("%s: idx=none", prefix);
|
||||
}
|
||||
|
||||
/* Find state from a session. */
|
||||
int
|
||||
cmd_find_from_session(struct cmd_find_state *fs, struct session *s)
|
||||
{
|
||||
cmd_find_clear_state(fs, NULL, 0);
|
||||
|
||||
fs->s = s;
|
||||
fs->wl = fs->s->curw;
|
||||
fs->w = fs->wl->window;
|
||||
fs->wp = fs->w->active;
|
||||
|
||||
cmd_find_log_state(__func__, fs);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Find state from a winlink. */
|
||||
int
|
||||
cmd_find_from_winlink(struct cmd_find_state *fs, struct session *s,
|
||||
struct winlink *wl)
|
||||
{
|
||||
cmd_find_clear_state(fs, NULL, 0);
|
||||
|
||||
fs->s = s;
|
||||
fs->wl = wl;
|
||||
fs->w = wl->window;
|
||||
fs->wp = wl->window->active;
|
||||
|
||||
cmd_find_log_state(__func__, fs);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Find state from a window. */
|
||||
int
|
||||
cmd_find_from_window(struct cmd_find_state *fs, struct window *w)
|
||||
{
|
||||
cmd_find_clear_state(fs, NULL, 0);
|
||||
|
||||
fs->w = w;
|
||||
if (cmd_find_best_session_with_window(fs) != 0)
|
||||
return (-1);
|
||||
if (cmd_find_best_winlink_with_window(fs) != 0)
|
||||
return (-1);
|
||||
|
||||
cmd_find_log_state(__func__, fs);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Find state from a pane. */
|
||||
int
|
||||
cmd_find_from_pane(struct cmd_find_state *fs, struct window_pane *wp)
|
||||
{
|
||||
if (cmd_find_from_window(fs, wp->window) != 0)
|
||||
return (-1);
|
||||
fs->wp = wp;
|
||||
|
||||
cmd_find_log_state(__func__, fs);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Find current state. */
|
||||
int
|
||||
cmd_find_current(struct cmd_find_state *fs, struct cmd_q *cmdq, int flags)
|
||||
{
|
||||
cmd_find_clear_state(fs, cmdq, flags);
|
||||
if (cmd_find_current_session(fs) != 0) {
|
||||
if (~flags & CMD_FIND_QUIET)
|
||||
cmdq_error(cmdq, "no current session");
|
||||
goto error;
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Split target into pieces and resolve for the given type. Fills in the given
|
||||
* state. Returns 0 on success or -1 on error.
|
||||
*/
|
||||
int
|
||||
cmd_find_target(struct cmd_find_state *fs, struct cmd_find_state *current,
|
||||
struct cmd_q *cmdq, const char *target, enum cmd_find_type type, int flags)
|
||||
{
|
||||
struct mouse_event *m;
|
||||
char *colon, *period, *copy = NULL;
|
||||
const char *session, *window, *pane;
|
||||
|
||||
/* Log the arguments. */
|
||||
if (target == NULL)
|
||||
log_debug("%s: target none, type %d", __func__, type);
|
||||
else
|
||||
log_debug("%s: target %s, type %d", __func__, target, type);
|
||||
log_debug("%s: cmdq %p, flags %#x", __func__, cmdq, flags);
|
||||
|
||||
/* Clear new state. */
|
||||
cmd_find_clear_state(&fs, cmdq, flags);
|
||||
fs.current = ¤t;
|
||||
cmd_find_clear_state(fs, cmdq, flags);
|
||||
|
||||
/* Find current state. */
|
||||
if (server_check_marked() && (flags & CMD_FIND_DEFAULT_MARKED))
|
||||
fs->current = &marked_pane;
|
||||
else if (cmd_find_valid_state(&cmdq->current))
|
||||
fs->current = &cmdq->current;
|
||||
else
|
||||
fs->current = current;
|
||||
|
||||
/* An empty or NULL target is the current. */
|
||||
if (target == NULL || *target == '\0')
|
||||
|
|
@ -800,25 +982,25 @@ cmd_find_target(struct cmd_q *cmdq, const char *target, enum cmd_find_type type,
|
|||
m = &cmdq->item->mouse;
|
||||
switch (type) {
|
||||
case CMD_FIND_PANE:
|
||||
fs.wp = cmd_mouse_pane(m, &fs.s, &fs.wl);
|
||||
if (fs.wp != NULL)
|
||||
fs.w = fs.wl->window;
|
||||
fs->wp = cmd_mouse_pane(m, &fs->s, &fs->wl);
|
||||
if (fs->wp != NULL)
|
||||
fs->w = fs->wl->window;
|
||||
break;
|
||||
case CMD_FIND_WINDOW:
|
||||
case CMD_FIND_SESSION:
|
||||
fs.wl = cmd_mouse_window(m, &fs.s);
|
||||
if (fs.wl != NULL) {
|
||||
fs.w = fs.wl->window;
|
||||
fs.wp = fs.w->active;
|
||||
fs->wl = cmd_mouse_window(m, &fs->s);
|
||||
if (fs->wl != NULL) {
|
||||
fs->w = fs->wl->window;
|
||||
fs->wp = fs->w->active;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (fs.wp == NULL) {
|
||||
if (fs->wp == NULL) {
|
||||
if (~flags & CMD_FIND_QUIET)
|
||||
cmdq_error(cmdq, "no mouse target");
|
||||
goto error;
|
||||
}
|
||||
return (&fs);
|
||||
goto found;
|
||||
}
|
||||
|
||||
/* Marked target is a plain ~ or {marked}. */
|
||||
|
|
@ -828,12 +1010,8 @@ cmd_find_target(struct cmd_q *cmdq, const char *target, enum cmd_find_type type,
|
|||
cmdq_error(cmdq, "no marked target");
|
||||
goto error;
|
||||
}
|
||||
fs.s = marked_session;
|
||||
fs.wl = marked_winlink;
|
||||
fs.idx = fs.wl->idx;
|
||||
fs.w = fs.wl->window;
|
||||
fs.wp = marked_window_pane;
|
||||
return (&fs);
|
||||
cmd_find_copy_state(fs, &marked_pane);
|
||||
goto found;
|
||||
}
|
||||
|
||||
/* Find separators if they exist. */
|
||||
|
|
@ -885,11 +1063,11 @@ cmd_find_target(struct cmd_q *cmdq, const char *target, enum cmd_find_type type,
|
|||
/* Set exact match flags. */
|
||||
if (session != NULL && *session == '=') {
|
||||
session++;
|
||||
fs.flags |= CMD_FIND_EXACT_SESSION;
|
||||
fs->flags |= CMD_FIND_EXACT_SESSION;
|
||||
}
|
||||
if (window != NULL && *window == '=') {
|
||||
window++;
|
||||
fs.flags |= CMD_FIND_EXACT_WINDOW;
|
||||
fs->flags |= CMD_FIND_EXACT_WINDOW;
|
||||
}
|
||||
|
||||
/* Empty is the same as NULL. */
|
||||
|
|
@ -922,32 +1100,31 @@ cmd_find_target(struct cmd_q *cmdq, const char *target, enum cmd_find_type type,
|
|||
/* If the session isn't NULL, look it up. */
|
||||
if (session != NULL) {
|
||||
/* This will fill in session. */
|
||||
if (cmd_find_get_session(&fs, session) != 0)
|
||||
if (cmd_find_get_session(fs, session) != 0)
|
||||
goto no_session;
|
||||
|
||||
/* If window and pane are NULL, use that session's current. */
|
||||
if (window == NULL && pane == NULL) {
|
||||
fs.wl = fs.s->curw;
|
||||
fs.idx = -1;
|
||||
fs.w = fs.wl->window;
|
||||
fs.wp = fs.w->active;
|
||||
fs->wl = fs->s->curw;
|
||||
fs->idx = -1;
|
||||
fs->w = fs->wl->window;
|
||||
fs->wp = fs->w->active;
|
||||
goto found;
|
||||
}
|
||||
|
||||
/* If window is present but pane not, find window in session. */
|
||||
if (window != NULL && pane == NULL) {
|
||||
/* This will fill in winlink and window. */
|
||||
if (cmd_find_get_window_with_session(&fs, window) != 0)
|
||||
if (cmd_find_get_window_with_session(fs, window) != 0)
|
||||
goto no_window;
|
||||
if (~flags & CMD_FIND_WINDOW_INDEX)
|
||||
fs.wp = fs.wl->window->active;
|
||||
fs->wp = fs->wl->window->active;
|
||||
goto found;
|
||||
}
|
||||
|
||||
/* If pane is present but window not, find pane. */
|
||||
if (window == NULL && pane != NULL) {
|
||||
/* This will fill in winlink and window and pane. */
|
||||
if (cmd_find_get_pane_with_session(&fs, pane) != 0)
|
||||
if (cmd_find_get_pane_with_session(fs, pane) != 0)
|
||||
goto no_pane;
|
||||
goto found;
|
||||
}
|
||||
|
|
@ -956,10 +1133,10 @@ cmd_find_target(struct cmd_q *cmdq, const char *target, enum cmd_find_type type,
|
|||
* If window and pane are present, find both in session. This
|
||||
* will fill in winlink and window.
|
||||
*/
|
||||
if (cmd_find_get_window_with_session(&fs, window) != 0)
|
||||
if (cmd_find_get_window_with_session(fs, window) != 0)
|
||||
goto no_window;
|
||||
/* This will fill in pane. */
|
||||
if (cmd_find_get_pane_with_window(&fs, pane) != 0)
|
||||
if (cmd_find_get_pane_with_window(fs, pane) != 0)
|
||||
goto no_pane;
|
||||
goto found;
|
||||
}
|
||||
|
|
@ -967,10 +1144,10 @@ cmd_find_target(struct cmd_q *cmdq, const char *target, enum cmd_find_type type,
|
|||
/* No session. If window and pane, try them. */
|
||||
if (window != NULL && pane != NULL) {
|
||||
/* This will fill in session, winlink and window. */
|
||||
if (cmd_find_get_window(&fs, window) != 0)
|
||||
if (cmd_find_get_window(fs, window) != 0)
|
||||
goto no_window;
|
||||
/* This will fill in pane. */
|
||||
if (cmd_find_get_pane_with_window(&fs, pane) != 0)
|
||||
if (cmd_find_get_pane_with_window(fs, pane) != 0)
|
||||
goto no_pane;
|
||||
goto found;
|
||||
}
|
||||
|
|
@ -978,35 +1155,40 @@ cmd_find_target(struct cmd_q *cmdq, const char *target, enum cmd_find_type type,
|
|||
/* If just window is present, try it. */
|
||||
if (window != NULL && pane == NULL) {
|
||||
/* This will fill in session, winlink and window. */
|
||||
if (cmd_find_get_window(&fs, window) != 0)
|
||||
if (cmd_find_get_window(fs, window) != 0)
|
||||
goto no_window;
|
||||
if (~flags & CMD_FIND_WINDOW_INDEX)
|
||||
fs.wp = fs.wl->window->active;
|
||||
fs->wp = fs->wl->window->active;
|
||||
goto found;
|
||||
}
|
||||
|
||||
/* If just pane is present, try it. */
|
||||
if (window == NULL && pane != NULL) {
|
||||
/* This will fill in session, winlink, window and pane. */
|
||||
if (cmd_find_get_pane(&fs, pane) != 0)
|
||||
if (cmd_find_get_pane(fs, pane) != 0)
|
||||
goto no_pane;
|
||||
goto found;
|
||||
}
|
||||
|
||||
current:
|
||||
/* None is the current session. */
|
||||
free(copy);
|
||||
/* Use the current session. */
|
||||
cmd_find_copy_state(fs, fs->current);
|
||||
if (flags & CMD_FIND_WINDOW_INDEX)
|
||||
current.idx = -1;
|
||||
return (¤t);
|
||||
fs->idx = -1;
|
||||
goto found;
|
||||
|
||||
error:
|
||||
fs->current = NULL;
|
||||
log_debug(" error");
|
||||
|
||||
free(copy);
|
||||
return (NULL);
|
||||
return (-1);
|
||||
|
||||
found:
|
||||
fs->current = NULL;
|
||||
cmd_find_log_state(__func__, fs);
|
||||
|
||||
free(copy);
|
||||
return (&fs);
|
||||
return (0);
|
||||
|
||||
no_session:
|
||||
if (~flags & CMD_FIND_QUIET)
|
||||
|
|
@ -1024,139 +1206,6 @@ no_pane:
|
|||
goto error;
|
||||
}
|
||||
|
||||
/* Log the result. */
|
||||
void
|
||||
cmd_find_log_state(const char *f, const char *target, struct cmd_find_state *fs)
|
||||
{
|
||||
log_debug("%s: target %s%s", f, target == NULL ? "none" : target,
|
||||
fs != NULL ? "" : " (failed)");
|
||||
if (fs == NULL)
|
||||
return;
|
||||
if (fs->s != NULL)
|
||||
log_debug("\ts=$%u", fs->s->id);
|
||||
else
|
||||
log_debug("\ts=none");
|
||||
if (fs->wl != NULL) {
|
||||
log_debug("\twl=%u %d w=@%u %s", fs->wl->idx,
|
||||
fs->wl->window == fs->w, fs->w->id, fs->w->name);
|
||||
} else
|
||||
log_debug("\twl=none");
|
||||
if (fs->wp != NULL)
|
||||
log_debug("\twp=%%%u", fs->wp->id);
|
||||
else
|
||||
log_debug("\twp=none");
|
||||
if (fs->idx != -1)
|
||||
log_debug("\tidx=%d", fs->idx);
|
||||
else
|
||||
log_debug("\tidx=none");
|
||||
}
|
||||
|
||||
/* Find the current session. */
|
||||
struct session *
|
||||
cmd_find_current(struct cmd_q *cmdq)
|
||||
{
|
||||
struct cmd_find_state *fs;
|
||||
int flags = CMD_FIND_QUIET;
|
||||
|
||||
fs = cmd_find_target(cmdq, NULL, CMD_FIND_SESSION, flags);
|
||||
cmd_find_log_state(__func__, NULL, fs);
|
||||
if (fs == NULL)
|
||||
return (NULL);
|
||||
|
||||
return (fs->s);
|
||||
}
|
||||
|
||||
/* Find the target session or report an error and return NULL. */
|
||||
struct session *
|
||||
cmd_find_session(struct cmd_q *cmdq, const char *target, int prefer_unattached)
|
||||
{
|
||||
struct cmd_find_state *fs;
|
||||
int flags = 0;
|
||||
|
||||
if (prefer_unattached)
|
||||
flags |= CMD_FIND_PREFER_UNATTACHED;
|
||||
|
||||
fs = cmd_find_target(cmdq, target, CMD_FIND_SESSION, flags);
|
||||
cmd_find_log_state(__func__, target, fs);
|
||||
if (fs == NULL)
|
||||
return (NULL);
|
||||
|
||||
return (fs->s);
|
||||
}
|
||||
|
||||
/* Find the target window or report an error and return NULL. */
|
||||
struct winlink *
|
||||
cmd_find_window(struct cmd_q *cmdq, const char *target, struct session **sp)
|
||||
{
|
||||
struct cmd_find_state *fs;
|
||||
|
||||
fs = cmd_find_target(cmdq, target, CMD_FIND_WINDOW, 0);
|
||||
cmd_find_log_state(__func__, target, fs);
|
||||
if (fs == NULL)
|
||||
return (NULL);
|
||||
|
||||
if (sp != NULL)
|
||||
*sp = fs->s;
|
||||
return (fs->wl);
|
||||
}
|
||||
|
||||
/* Find the target window, defaulting to marked rather than current. */
|
||||
struct winlink *
|
||||
cmd_find_window_marked(struct cmd_q *cmdq, const char *target,
|
||||
struct session **sp)
|
||||
{
|
||||
struct cmd_find_state *fs;
|
||||
int flags = CMD_FIND_DEFAULT_MARKED;
|
||||
|
||||
fs = cmd_find_target(cmdq, target, CMD_FIND_WINDOW, flags);
|
||||
cmd_find_log_state(__func__, target, fs);
|
||||
if (fs == NULL)
|
||||
return (NULL);
|
||||
|
||||
if (sp != NULL)
|
||||
*sp = fs->s;
|
||||
return (fs->wl);
|
||||
}
|
||||
|
||||
/* Find the target pane and report an error and return NULL. */
|
||||
struct winlink *
|
||||
cmd_find_pane(struct cmd_q *cmdq, const char *target, struct session **sp,
|
||||
struct window_pane **wpp)
|
||||
{
|
||||
struct cmd_find_state *fs;
|
||||
|
||||
fs = cmd_find_target(cmdq, target, CMD_FIND_PANE, 0);
|
||||
cmd_find_log_state(__func__, target, fs);
|
||||
if (fs == NULL)
|
||||
return (NULL);
|
||||
|
||||
if (sp != NULL)
|
||||
*sp = fs->s;
|
||||
if (wpp != NULL)
|
||||
*wpp = fs->wp;
|
||||
return (fs->wl);
|
||||
}
|
||||
|
||||
/* Find the target pane, defaulting to marked rather than current. */
|
||||
struct winlink *
|
||||
cmd_find_pane_marked(struct cmd_q *cmdq, const char *target,
|
||||
struct session **sp, struct window_pane **wpp)
|
||||
{
|
||||
struct cmd_find_state *fs;
|
||||
int flags = CMD_FIND_DEFAULT_MARKED;
|
||||
|
||||
fs = cmd_find_target(cmdq, target, CMD_FIND_PANE, flags);
|
||||
cmd_find_log_state(__func__, target, fs);
|
||||
if (fs == NULL)
|
||||
return (NULL);
|
||||
|
||||
if (sp != NULL)
|
||||
*sp = fs->s;
|
||||
if (wpp != NULL)
|
||||
*wpp = fs->wp;
|
||||
return (fs->wl);
|
||||
}
|
||||
|
||||
/* Find the target client or report an error and return NULL. */
|
||||
struct client *
|
||||
cmd_find_client(struct cmd_q *cmdq, const char *target, int quiet)
|
||||
|
|
@ -1167,10 +1216,11 @@ cmd_find_client(struct cmd_q *cmdq, const char *target, int quiet)
|
|||
const char *path;
|
||||
|
||||
/* A NULL argument means the current client. */
|
||||
if (target == NULL) {
|
||||
if (cmdq != NULL && target == NULL) {
|
||||
c = cmd_find_current_client(cmdq);
|
||||
if (c == NULL && !quiet)
|
||||
cmdq_error(cmdq, "no current client");
|
||||
log_debug("%s: no target, return %p", __func__, c);
|
||||
return (c);
|
||||
}
|
||||
copy = xstrdup(target);
|
||||
|
|
@ -1202,27 +1252,6 @@ cmd_find_client(struct cmd_q *cmdq, const char *target, int quiet)
|
|||
cmdq_error(cmdq, "can't find client %s", copy);
|
||||
|
||||
free(copy);
|
||||
log_debug("%s: target %s, return %p", __func__, target, c);
|
||||
return (c);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the target session and window index, whether or not it exists in the
|
||||
* session. Return -2 on error or -1 if no window index is specified. This is
|
||||
* used when parsing an argument for a window target that may not exist (for
|
||||
* example if it is going to be created).
|
||||
*/
|
||||
int
|
||||
cmd_find_index(struct cmd_q *cmdq, const char *target, struct session **sp)
|
||||
{
|
||||
struct cmd_find_state *fs;
|
||||
int flags = CMD_FIND_WINDOW_INDEX;
|
||||
|
||||
fs = cmd_find_target(cmdq, target, CMD_FIND_WINDOW, flags);
|
||||
cmd_find_log_state(__func__, target, fs);
|
||||
if (fs == NULL)
|
||||
return (-2);
|
||||
|
||||
if (sp != NULL)
|
||||
*sp = fs->s;
|
||||
return (fs->idx);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,11 +36,17 @@ void cmd_if_shell_done(struct cmd_q *);
|
|||
void cmd_if_shell_free(void *);
|
||||
|
||||
const struct cmd_entry cmd_if_shell_entry = {
|
||||
"if-shell", "if",
|
||||
"bFt:", 2, 3,
|
||||
"[-bF] " CMD_TARGET_PANE_USAGE " shell-command command [command]",
|
||||
0,
|
||||
cmd_if_shell_exec
|
||||
.name = "if-shell",
|
||||
.alias = "if",
|
||||
|
||||
.args = { "bFt:", 2, 3 },
|
||||
.usage = "[-bF] " CMD_TARGET_PANE_USAGE " shell-command command "
|
||||
"[command]",
|
||||
|
||||
.tflag = CMD_PANE_CANFAIL,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_if_shell_exec
|
||||
};
|
||||
|
||||
struct cmd_if_shell_data {
|
||||
|
|
@ -61,32 +67,20 @@ cmd_if_shell_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
struct cmd_if_shell_data *cdata;
|
||||
char *shellcmd, *cmd, *cause;
|
||||
struct cmd_list *cmdlist;
|
||||
struct client *c;
|
||||
struct session *s = NULL;
|
||||
struct winlink *wl = NULL;
|
||||
struct window_pane *wp = NULL;
|
||||
struct session *s = cmdq->state.tflag.s;
|
||||
struct winlink *wl = cmdq->state.tflag.wl;
|
||||
struct window_pane *wp = cmdq->state.tflag.wp;
|
||||
struct format_tree *ft;
|
||||
int cwd;
|
||||
const char *cwd;
|
||||
|
||||
if (args_has(args, 't')) {
|
||||
wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp);
|
||||
cwd = wp->cwd;
|
||||
} else {
|
||||
c = cmd_find_client(cmdq, NULL, 1);
|
||||
if (c != NULL && c->session != NULL) {
|
||||
s = c->session;
|
||||
wl = s->curw;
|
||||
wp = wl->window->active;
|
||||
}
|
||||
if (cmdq->client != NULL && cmdq->client->session == NULL)
|
||||
cwd = cmdq->client->cwd;
|
||||
else if (s != NULL)
|
||||
cwd = s->cwd;
|
||||
else
|
||||
cwd = -1;
|
||||
}
|
||||
if (cmdq->client != NULL && cmdq->client->session == NULL)
|
||||
cwd = cmdq->client->cwd;
|
||||
else if (s != NULL)
|
||||
cwd = s->cwd;
|
||||
else
|
||||
cwd = NULL;
|
||||
|
||||
ft = format_create();
|
||||
ft = format_create(cmdq, 0);
|
||||
format_defaults(ft, NULL, s, wl, wp);
|
||||
shellcmd = format_expand(ft, args->argv[0]);
|
||||
format_free(ft);
|
||||
|
|
@ -97,6 +91,7 @@ cmd_if_shell_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
cmd = args->argv[1];
|
||||
else if (args->argc == 3)
|
||||
cmd = args->argv[2];
|
||||
free(shellcmd);
|
||||
if (cmd == NULL)
|
||||
return (CMD_RETURN_NORMAL);
|
||||
if (cmd_string_parse(cmd, &cmdlist, NULL, 0, &cause) != 0) {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
/*
|
||||
* Copyright (c) 2011 George Nachman <tmux@georgester.com>
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -33,19 +33,31 @@ enum cmd_retval cmd_join_pane_exec(struct cmd *, struct cmd_q *);
|
|||
enum cmd_retval join_pane(struct cmd *, struct cmd_q *, int);
|
||||
|
||||
const struct cmd_entry cmd_join_pane_entry = {
|
||||
"join-pane", "joinp",
|
||||
"bdhvp:l:s:t:", 0, 0,
|
||||
"[-bdhv] [-p percentage|-l size] " CMD_SRCDST_PANE_USAGE,
|
||||
0,
|
||||
cmd_join_pane_exec
|
||||
.name = "join-pane",
|
||||
.alias = "joinp",
|
||||
|
||||
.args = { "bdhvp:l:s:t:", 0, 0 },
|
||||
.usage = "[-bdhv] [-p percentage|-l size] " CMD_SRCDST_PANE_USAGE,
|
||||
|
||||
.sflag = CMD_PANE_MARKED,
|
||||
.tflag = CMD_PANE,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_join_pane_exec
|
||||
};
|
||||
|
||||
const struct cmd_entry cmd_move_pane_entry = {
|
||||
"move-pane", "movep",
|
||||
"bdhvp:l:s:t:", 0, 0,
|
||||
"[-bdhv] [-p percentage|-l size] " CMD_SRCDST_PANE_USAGE,
|
||||
0,
|
||||
cmd_join_pane_exec
|
||||
.name = "move-pane",
|
||||
.alias = "movep",
|
||||
|
||||
.args = { "bdhvp:l:s:t:", 0, 0 },
|
||||
.usage = "[-bdhv] [-p percentage|-l size] " CMD_SRCDST_PANE_USAGE,
|
||||
|
||||
.sflag = CMD_PANE,
|
||||
.tflag = CMD_PANE,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_join_pane_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
|
|
@ -57,6 +69,10 @@ cmd_join_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
enum cmd_retval
|
||||
join_pane(struct cmd *self, struct cmd_q *cmdq, int not_same_window)
|
||||
{
|
||||
#ifdef TMATE
|
||||
cmdq_error(cmdq, "join pane is not supported with tmate");
|
||||
return (CMD_RETURN_ERROR);
|
||||
#else
|
||||
struct args *args = self->args;
|
||||
struct session *dst_s;
|
||||
struct winlink *src_wl, *dst_wl;
|
||||
|
|
@ -67,16 +83,15 @@ join_pane(struct cmd *self, struct cmd_q *cmdq, int not_same_window)
|
|||
enum layout_type type;
|
||||
struct layout_cell *lc;
|
||||
|
||||
dst_wl = cmd_find_pane(cmdq, args_get(args, 't'), &dst_s, &dst_wp);
|
||||
if (dst_wl == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
dst_s = cmdq->state.tflag.s;
|
||||
dst_wl = cmdq->state.tflag.wl;
|
||||
dst_wp = cmdq->state.tflag.wp;
|
||||
dst_w = dst_wl->window;
|
||||
dst_idx = dst_wl->idx;
|
||||
server_unzoom_window(dst_w);
|
||||
|
||||
src_wl = cmd_find_pane_marked(cmdq, args_get(args, 's'), NULL, &src_wp);
|
||||
if (src_wl == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
src_wl = cmdq->state.sflag.wl;
|
||||
src_wp = cmdq->state.sflag.wp;
|
||||
src_w = src_wl->window;
|
||||
server_unzoom_window(src_w);
|
||||
|
||||
|
|
@ -147,4 +162,5 @@ join_pane(struct cmd *self, struct cmd_q *cmdq, int not_same_window)
|
|||
|
||||
notify_window_layout_changed(dst_w);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -29,22 +29,24 @@
|
|||
enum cmd_retval cmd_kill_pane_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_kill_pane_entry = {
|
||||
"kill-pane", "killp",
|
||||
"at:", 0, 0,
|
||||
"[-a] " CMD_TARGET_PANE_USAGE,
|
||||
0,
|
||||
cmd_kill_pane_exec
|
||||
.name = "kill-pane",
|
||||
.alias = "killp",
|
||||
|
||||
.args = { "at:", 0, 0 },
|
||||
.usage = "[-a] " CMD_TARGET_PANE_USAGE,
|
||||
|
||||
.tflag = CMD_PANE,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_kill_pane_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_kill_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct winlink *wl;
|
||||
struct window_pane *loopwp, *tmpwp, *wp;
|
||||
struct winlink *wl = cmdq->state.tflag.wl;
|
||||
struct window_pane *loopwp, *tmpwp, *wp = cmdq->state.tflag.wp;
|
||||
|
||||
if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
server_unzoom_window(wl->window);
|
||||
|
||||
if (window_count_panes(wl->window) == 1) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -30,23 +30,29 @@
|
|||
enum cmd_retval cmd_kill_server_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_kill_server_entry = {
|
||||
"kill-server", NULL,
|
||||
"", 0, 0,
|
||||
"",
|
||||
0,
|
||||
cmd_kill_server_exec
|
||||
.name = "kill-server",
|
||||
.alias = NULL,
|
||||
|
||||
.args = { "", 0, 0 },
|
||||
.usage = "",
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_kill_server_exec
|
||||
};
|
||||
|
||||
const struct cmd_entry cmd_start_server_entry = {
|
||||
"start-server", "start",
|
||||
"", 0, 0,
|
||||
"",
|
||||
CMD_STARTSERVER,
|
||||
cmd_kill_server_exec
|
||||
.name = "start-server",
|
||||
.alias = "start",
|
||||
|
||||
.args = { "", 0, 0 },
|
||||
.usage = "",
|
||||
|
||||
.flags = CMD_STARTSERVER,
|
||||
.exec = cmd_kill_server_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_kill_server_exec(struct cmd *self, unused struct cmd_q *cmdq)
|
||||
cmd_kill_server_exec(struct cmd *self, __unused struct cmd_q *cmdq)
|
||||
{
|
||||
if (self->entry == &cmd_kill_server_entry)
|
||||
kill(getpid(), SIGTERM);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -30,11 +30,16 @@
|
|||
enum cmd_retval cmd_kill_session_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_kill_session_entry = {
|
||||
"kill-session", NULL,
|
||||
"at:", 0, 0,
|
||||
"[-a] " CMD_TARGET_SESSION_USAGE,
|
||||
0,
|
||||
cmd_kill_session_exec
|
||||
.name = "kill-session",
|
||||
.alias = NULL,
|
||||
|
||||
.args = { "aCt:", 0, 0 },
|
||||
.usage = "[-aC] " CMD_TARGET_SESSION_USAGE,
|
||||
|
||||
.tflag = CMD_SESSION,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_kill_session_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
|
|
@ -42,11 +47,17 @@ cmd_kill_session_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
{
|
||||
struct args *args = self->args;
|
||||
struct session *s, *sloop, *stmp;
|
||||
struct winlink *wl;
|
||||
|
||||
if ((s = cmd_find_session(cmdq, args_get(args, 't'), 0)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
s = cmdq->state.tflag.s;
|
||||
|
||||
if (args_has(args, 'a')) {
|
||||
if (args_has(args, 'C')) {
|
||||
RB_FOREACH(wl, winlinks, &s->windows) {
|
||||
wl->window->flags &= ~WINDOW_ALERTFLAGS;
|
||||
wl->flags &= ~WINLINK_ALERTFLAGS;
|
||||
}
|
||||
server_redraw_session(s);
|
||||
} else if (args_has(args, 'a')) {
|
||||
RB_FOREACH_SAFE(sloop, sessions, &sessions, stmp) {
|
||||
if (sloop != s) {
|
||||
server_destroy_session(sloop);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -27,32 +27,38 @@
|
|||
enum cmd_retval cmd_kill_window_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_kill_window_entry = {
|
||||
"kill-window", "killw",
|
||||
"at:", 0, 0,
|
||||
"[-a] " CMD_TARGET_WINDOW_USAGE,
|
||||
0,
|
||||
cmd_kill_window_exec
|
||||
.name = "kill-window",
|
||||
.alias = "killw",
|
||||
|
||||
.args = { "at:", 0, 0 },
|
||||
.usage = "[-a] " CMD_TARGET_WINDOW_USAGE,
|
||||
|
||||
.tflag = CMD_WINDOW,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_kill_window_exec
|
||||
};
|
||||
|
||||
const struct cmd_entry cmd_unlink_window_entry = {
|
||||
"unlink-window", "unlinkw",
|
||||
"kt:", 0, 0,
|
||||
"[-k] " CMD_TARGET_WINDOW_USAGE,
|
||||
0,
|
||||
cmd_kill_window_exec
|
||||
.name = "unlink-window",
|
||||
.alias = "unlinkw",
|
||||
|
||||
.args = { "kt:", 0, 0 },
|
||||
.usage = "[-k] " CMD_TARGET_WINDOW_USAGE,
|
||||
|
||||
.tflag = CMD_WINDOW,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_kill_window_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_kill_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct winlink *wl, *wl2, *wl3;
|
||||
struct window *w;
|
||||
struct session *s;
|
||||
|
||||
if ((wl = cmd_find_window(cmdq, args_get(args, 't'), &s)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
w = wl->window;
|
||||
struct args *args = self->args;
|
||||
struct winlink *wl = cmdq->state.tflag.wl, *wl2, *wl3;
|
||||
struct window *w = wl->window;
|
||||
struct session *s = cmdq->state.tflag.s;
|
||||
|
||||
if (self->entry == &cmd_unlink_window_entry) {
|
||||
if (!args_has(self->args, 'k') && !session_is_linked(s, w)) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -33,15 +33,18 @@
|
|||
enum cmd_retval cmd_list_buffers_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_list_buffers_entry = {
|
||||
"list-buffers", "lsb",
|
||||
"F:", 0, 0,
|
||||
"[-F format]",
|
||||
0,
|
||||
cmd_list_buffers_exec
|
||||
.name = "list-buffers",
|
||||
.alias = "lsb",
|
||||
|
||||
.args = { "F:", 0, 0 },
|
||||
.usage = "[-F format]",
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_list_buffers_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_list_buffers_exec(unused struct cmd *self, struct cmd_q *cmdq)
|
||||
cmd_list_buffers_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct paste_buffer *pb;
|
||||
|
|
@ -54,8 +57,8 @@ cmd_list_buffers_exec(unused struct cmd *self, struct cmd_q *cmdq)
|
|||
|
||||
pb = NULL;
|
||||
while ((pb = paste_walk(pb)) != NULL) {
|
||||
ft = format_create();
|
||||
format_defaults_paste_buffer(ft, pb, 0);
|
||||
ft = format_create(cmdq, 0);
|
||||
format_defaults_paste_buffer(ft, pb);
|
||||
|
||||
line = format_expand(ft, template);
|
||||
cmdq_print(cmdq, "%s", line);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -36,11 +36,16 @@
|
|||
enum cmd_retval cmd_list_clients_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_list_clients_entry = {
|
||||
"list-clients", "lsc",
|
||||
"F:t:", 0, 0,
|
||||
"[-F format] " CMD_TARGET_SESSION_USAGE,
|
||||
CMD_READONLY,
|
||||
cmd_list_clients_exec
|
||||
.name = "list-clients",
|
||||
.alias = "lsc",
|
||||
|
||||
.args = { "F:t:", 0, 0 },
|
||||
.usage = "[-F format] " CMD_TARGET_SESSION_USAGE,
|
||||
|
||||
.tflag = CMD_SESSION,
|
||||
|
||||
.flags = CMD_READONLY,
|
||||
.exec = cmd_list_clients_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
|
|
@ -54,11 +59,9 @@ cmd_list_clients_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
u_int idx;
|
||||
char *line;
|
||||
|
||||
if (args_has(args, 't')) {
|
||||
s = cmd_find_session(cmdq, args_get(args, 't'), 0);
|
||||
if (s == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
} else
|
||||
if (args_has(args, 't'))
|
||||
s = cmdq->state.tflag.s;
|
||||
else
|
||||
s = NULL;
|
||||
|
||||
if ((template = args_get(args, 'F')) == NULL)
|
||||
|
|
@ -69,7 +72,7 @@ cmd_list_clients_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
if (c->session == NULL || (s != NULL && s != c->session))
|
||||
continue;
|
||||
|
||||
ft = format_create();
|
||||
ft = format_create(cmdq, 0);
|
||||
format_add(ft, "line", "%u", idx);
|
||||
format_defaults(ft, c, NULL, NULL, NULL);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "tmux.h"
|
||||
|
|
@ -29,22 +30,28 @@
|
|||
enum cmd_retval cmd_list_keys_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
enum cmd_retval cmd_list_keys_table(struct cmd *, struct cmd_q *);
|
||||
enum cmd_retval cmd_list_keys_commands(struct cmd *, struct cmd_q *);
|
||||
enum cmd_retval cmd_list_keys_commands(struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_list_keys_entry = {
|
||||
"list-keys", "lsk",
|
||||
"t:T:", 0, 0,
|
||||
"[-t mode-table] [-T key-table]",
|
||||
0,
|
||||
cmd_list_keys_exec
|
||||
.name = "list-keys",
|
||||
.alias = "lsk",
|
||||
|
||||
.args = { "t:T:", 0, 0 },
|
||||
.usage = "[-t mode-table] [-T key-table]",
|
||||
|
||||
.flags = CMD_STARTSERVER,
|
||||
.exec = cmd_list_keys_exec
|
||||
};
|
||||
|
||||
const struct cmd_entry cmd_list_commands_entry = {
|
||||
"list-commands", "lscm",
|
||||
"", 0, 0,
|
||||
"",
|
||||
0,
|
||||
cmd_list_keys_exec
|
||||
.name = "list-commands",
|
||||
.alias = "lscm",
|
||||
|
||||
.args = { "", 0, 0 },
|
||||
.usage = "",
|
||||
|
||||
.flags = CMD_STARTSERVER,
|
||||
.exec = cmd_list_keys_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
|
|
@ -54,12 +61,21 @@ cmd_list_keys_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
struct key_table *table;
|
||||
struct key_binding *bd;
|
||||
const char *key, *tablename, *r;
|
||||
char tmp[BUFSIZ];
|
||||
size_t used;
|
||||
char *cp, tmp[BUFSIZ];
|
||||
int repeat, width, tablewidth, keywidth;
|
||||
|
||||
if (self->entry == &cmd_list_commands_entry)
|
||||
return (cmd_list_keys_commands(self, cmdq));
|
||||
return (cmd_list_keys_commands(cmdq));
|
||||
|
||||
#ifdef TMATE
|
||||
/* XXX TODO Really nasty hack, we really need our own client instance... */
|
||||
struct client fake_client;
|
||||
if (!cmdq->client) {
|
||||
cmdq->client = &fake_client;
|
||||
cmdq->client->flags = 0;
|
||||
cmdq->client->session = RB_MIN(sessions, &sessions);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (args_has(args, 't'))
|
||||
return (cmd_list_keys_table(self, cmdq));
|
||||
|
|
@ -77,16 +93,14 @@ cmd_list_keys_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
continue;
|
||||
RB_FOREACH(bd, key_bindings, &table->key_bindings) {
|
||||
key = key_string_lookup_key(bd->key);
|
||||
if (key == NULL)
|
||||
continue;
|
||||
|
||||
if (bd->can_repeat)
|
||||
repeat = 1;
|
||||
|
||||
width = strlen(table->name);
|
||||
width = utf8_cstrwidth(table->name);
|
||||
if (width > tablewidth)
|
||||
tablewidth =width;
|
||||
width = strlen(key);
|
||||
tablewidth = width;
|
||||
width = utf8_cstrwidth(key);
|
||||
if (width > keywidth)
|
||||
keywidth = width;
|
||||
}
|
||||
|
|
@ -97,8 +111,6 @@ cmd_list_keys_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
continue;
|
||||
RB_FOREACH(bd, key_bindings, &table->key_bindings) {
|
||||
key = key_string_lookup_key(bd->key);
|
||||
if (key == NULL)
|
||||
continue;
|
||||
|
||||
if (!repeat)
|
||||
r = "";
|
||||
|
|
@ -106,12 +118,21 @@ cmd_list_keys_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
r = "-r ";
|
||||
else
|
||||
r = " ";
|
||||
used = xsnprintf(tmp, sizeof tmp, "%s-T %-*s %-*s ", r,
|
||||
(int)tablewidth, table->name, (int)keywidth, key);
|
||||
if (used < sizeof tmp) {
|
||||
cmd_list_print(bd->cmdlist, tmp + used,
|
||||
(sizeof tmp) - used);
|
||||
}
|
||||
xsnprintf(tmp, sizeof tmp, "%s-T ", r);
|
||||
|
||||
cp = utf8_padcstr(table->name, tablewidth);
|
||||
strlcat(tmp, cp, sizeof tmp);
|
||||
strlcat(tmp, " ", sizeof tmp);
|
||||
free(cp);
|
||||
|
||||
cp = utf8_padcstr(key, keywidth);
|
||||
strlcat(tmp, cp, sizeof tmp);
|
||||
strlcat(tmp, " ", sizeof tmp);
|
||||
free(cp);
|
||||
|
||||
cp = cmd_list_print(bd->cmdlist);
|
||||
strlcat(tmp, cp, sizeof tmp);
|
||||
free(cp);
|
||||
|
||||
cmdq_print(cmdq, "bind-key %s", tmp);
|
||||
}
|
||||
|
|
@ -140,8 +161,6 @@ cmd_list_keys_table(struct cmd *self, struct cmd_q *cmdq)
|
|||
any_mode = 0;
|
||||
RB_FOREACH(mbind, mode_key_tree, mtab->tree) {
|
||||
key = key_string_lookup_key(mbind->key);
|
||||
if (key == NULL)
|
||||
continue;
|
||||
|
||||
if (mbind->mode != 0)
|
||||
any_mode = 1;
|
||||
|
|
@ -153,8 +172,6 @@ cmd_list_keys_table(struct cmd *self, struct cmd_q *cmdq)
|
|||
|
||||
RB_FOREACH(mbind, mode_key_tree, mtab->tree) {
|
||||
key = key_string_lookup_key(mbind->key);
|
||||
if (key == NULL)
|
||||
continue;
|
||||
|
||||
mode = "";
|
||||
if (mbind->mode != 0)
|
||||
|
|
@ -174,7 +191,7 @@ cmd_list_keys_table(struct cmd *self, struct cmd_q *cmdq)
|
|||
}
|
||||
|
||||
enum cmd_retval
|
||||
cmd_list_keys_commands(unused struct cmd *self, struct cmd_q *cmdq)
|
||||
cmd_list_keys_commands(struct cmd_q *cmdq)
|
||||
{
|
||||
const struct cmd_entry **entryp;
|
||||
const struct cmd_entry *entry;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -35,33 +35,31 @@ void cmd_list_panes_window(struct cmd *, struct session *, struct winlink *,
|
|||
struct cmd_q *, int);
|
||||
|
||||
const struct cmd_entry cmd_list_panes_entry = {
|
||||
"list-panes", "lsp",
|
||||
"asF:t:", 0, 0,
|
||||
"[-as] [-F format] " CMD_TARGET_WINDOW_USAGE,
|
||||
0,
|
||||
cmd_list_panes_exec
|
||||
.name = "list-panes",
|
||||
.alias = "lsp",
|
||||
|
||||
.args = { "asF:t:", 0, 0 },
|
||||
.usage = "[-as] [-F format] " CMD_TARGET_WINDOW_USAGE,
|
||||
|
||||
.tflag = CMD_WINDOW,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_list_panes_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_list_panes_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct session *s;
|
||||
struct winlink *wl;
|
||||
struct session *s = cmdq->state.tflag.s;
|
||||
struct winlink *wl = cmdq->state.tflag.wl;
|
||||
|
||||
if (args_has(args, 'a'))
|
||||
cmd_list_panes_server(self, cmdq);
|
||||
else if (args_has(args, 's')) {
|
||||
s = cmd_find_session(cmdq, args_get(args, 't'), 0);
|
||||
if (s == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
else if (args_has(args, 's'))
|
||||
cmd_list_panes_session(self, s, cmdq, 1);
|
||||
} else {
|
||||
wl = cmd_find_window(cmdq, args_get(args, 't'), &s);
|
||||
if (wl == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
else
|
||||
cmd_list_panes_window(self, s, wl, cmdq, 0);
|
||||
}
|
||||
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
|
@ -125,7 +123,7 @@ cmd_list_panes_window(struct cmd *self, struct session *s, struct winlink *wl,
|
|||
|
||||
n = 0;
|
||||
TAILQ_FOREACH(wp, &wl->window->panes, entry) {
|
||||
ft = format_create();
|
||||
ft = format_create(cmdq, 0);
|
||||
format_add(ft, "line", "%u", n);
|
||||
format_defaults(ft, NULL, s, wl, wp);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
#define LIST_SESSIONS_TEMPLATE \
|
||||
"#{session_name}: #{session_windows} windows " \
|
||||
"(created #{session_created_string}) " \
|
||||
"(created #{t:session_created}) " \
|
||||
"[#{session_width}x#{session_height}]" \
|
||||
"#{?session_grouped, (group ,}" \
|
||||
"#{session_group}#{?session_grouped,),}" \
|
||||
|
|
@ -39,11 +39,14 @@
|
|||
enum cmd_retval cmd_list_sessions_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_list_sessions_entry = {
|
||||
"list-sessions", "ls",
|
||||
"F:", 0, 0,
|
||||
"[-F format]",
|
||||
0,
|
||||
cmd_list_sessions_exec
|
||||
.name = "list-sessions",
|
||||
.alias = "ls",
|
||||
|
||||
.args = { "F:", 0, 0 },
|
||||
.usage = "[-F format]",
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_list_sessions_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
|
|
@ -61,7 +64,7 @@ cmd_list_sessions_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
|
||||
n = 0;
|
||||
RB_FOREACH(s, sessions, &sessions) {
|
||||
ft = format_create();
|
||||
ft = format_create(cmdq, 0);
|
||||
format_add(ft, "line", "%u", n);
|
||||
format_defaults(ft, NULL, s, NULL, NULL);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -46,27 +46,27 @@ void cmd_list_windows_session(struct cmd *, struct session *,
|
|||
struct cmd_q *, int);
|
||||
|
||||
const struct cmd_entry cmd_list_windows_entry = {
|
||||
"list-windows", "lsw",
|
||||
"F:at:", 0, 0,
|
||||
"[-a] [-F format] " CMD_TARGET_SESSION_USAGE,
|
||||
0,
|
||||
cmd_list_windows_exec
|
||||
.name = "list-windows",
|
||||
.alias = "lsw",
|
||||
|
||||
.args = { "F:at:", 0, 0 },
|
||||
.usage = "[-a] [-F format] " CMD_TARGET_SESSION_USAGE,
|
||||
|
||||
.tflag = CMD_SESSION,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_list_windows_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_list_windows_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct session *s;
|
||||
|
||||
if (args_has(args, 'a'))
|
||||
cmd_list_windows_server(self, cmdq);
|
||||
else {
|
||||
s = cmd_find_session(cmdq, args_get(args, 't'), 0);
|
||||
if (s == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
cmd_list_windows_session(self, s, cmdq, 0);
|
||||
}
|
||||
else
|
||||
cmd_list_windows_session(self, cmdq->state.tflag.s, cmdq, 0);
|
||||
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
|
@ -81,8 +81,8 @@ cmd_list_windows_server(struct cmd *self, struct cmd_q *cmdq)
|
|||
}
|
||||
|
||||
void
|
||||
cmd_list_windows_session(
|
||||
struct cmd *self, struct session *s, struct cmd_q *cmdq, int type)
|
||||
cmd_list_windows_session(struct cmd *self, struct session *s,
|
||||
struct cmd_q *cmdq, int type)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct winlink *wl;
|
||||
|
|
@ -105,7 +105,7 @@ cmd_list_windows_session(
|
|||
|
||||
n = 0;
|
||||
RB_FOREACH(wl, winlinks, &s->windows) {
|
||||
ft = format_create();
|
||||
ft = format_create(cmdq, 0);
|
||||
format_add(ft, "line", "%u", n);
|
||||
format_defaults(ft, NULL, s, wl, NULL);
|
||||
|
||||
|
|
|
|||
37
cmd-list.c
37
cmd-list.c
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -99,25 +99,28 @@ cmd_list_free(struct cmd_list *cmdlist)
|
|||
free(cmdlist);
|
||||
}
|
||||
|
||||
size_t
|
||||
cmd_list_print(struct cmd_list *cmdlist, char *buf, size_t len)
|
||||
char *
|
||||
cmd_list_print(struct cmd_list *cmdlist)
|
||||
{
|
||||
struct cmd *cmd;
|
||||
size_t off, used;
|
||||
char *buf, *this;
|
||||
size_t len;
|
||||
|
||||
len = 1;
|
||||
buf = xcalloc(1, len);
|
||||
|
||||
off = 0;
|
||||
TAILQ_FOREACH(cmd, &cmdlist->list, qentry) {
|
||||
if (off >= len)
|
||||
break;
|
||||
off += cmd_print(cmd, buf + off, len - off);
|
||||
if (off >= len)
|
||||
break;
|
||||
if (TAILQ_NEXT(cmd, qentry) != NULL) {
|
||||
used = xsnprintf(buf + off, len - off, " ; ");
|
||||
if (used > len - off)
|
||||
used = len - off;
|
||||
off += used;
|
||||
}
|
||||
this = cmd_print(cmd);
|
||||
|
||||
len += strlen(this) + 3;
|
||||
buf = xrealloc(buf, len);
|
||||
|
||||
strlcat(buf, this, len);
|
||||
if (TAILQ_NEXT(cmd, qentry) != NULL)
|
||||
strlcat(buf, " ; ", len);
|
||||
|
||||
free(this);
|
||||
}
|
||||
return (off);
|
||||
|
||||
return (buf);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,11 +35,14 @@ enum cmd_retval cmd_load_buffer_exec(struct cmd *, struct cmd_q *);
|
|||
void cmd_load_buffer_callback(struct client *, int, void *);
|
||||
|
||||
const struct cmd_entry cmd_load_buffer_entry = {
|
||||
"load-buffer", "loadb",
|
||||
"b:", 1, 1,
|
||||
CMD_BUFFER_USAGE " path",
|
||||
0,
|
||||
cmd_load_buffer_exec
|
||||
.name = "load-buffer",
|
||||
.alias = "loadb",
|
||||
|
||||
.args = { "b:", 1, 1 },
|
||||
.usage = CMD_BUFFER_USAGE " path",
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_load_buffer_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
|
|
@ -49,10 +52,10 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
struct client *c = cmdq->client;
|
||||
struct session *s;
|
||||
FILE *f;
|
||||
const char *path, *bufname;
|
||||
char *pdata, *new_pdata, *cause;
|
||||
const char *path, *bufname, *cwd;
|
||||
char *pdata, *new_pdata, *cause, *file, resolved[PATH_MAX];
|
||||
size_t psize;
|
||||
int ch, error, cwd, fd;
|
||||
int ch, error;
|
||||
|
||||
bufname = NULL;
|
||||
if (args_has(args, 'b'))
|
||||
|
|
@ -70,18 +73,26 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
return (CMD_RETURN_WAIT);
|
||||
}
|
||||
|
||||
if (c != NULL && c->session == NULL)
|
||||
if (c != NULL && c->session == NULL && c->cwd != NULL)
|
||||
cwd = c->cwd;
|
||||
else if ((s = cmd_find_current(cmdq)) != NULL)
|
||||
else if ((s = c->session) != NULL && s->cwd != NULL)
|
||||
cwd = s->cwd;
|
||||
else
|
||||
cwd = AT_FDCWD;
|
||||
cwd = ".";
|
||||
|
||||
if ((fd = openat(cwd, path, O_RDONLY)) == -1 ||
|
||||
(f = fdopen(fd, "rb")) == NULL) {
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
cmdq_error(cmdq, "%s: %s", path, strerror(errno));
|
||||
if (*path == '/')
|
||||
file = xstrdup(path);
|
||||
else
|
||||
xasprintf(&file, "%s/%s", cwd, path);
|
||||
if (realpath(file, resolved) == NULL &&
|
||||
strlcpy(resolved, file, sizeof resolved) >= sizeof resolved) {
|
||||
cmdq_error(cmdq, "%s: %s", file, strerror(ENAMETOOLONG));
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
f = fopen(resolved, "rb");
|
||||
free(file);
|
||||
if (f == NULL) {
|
||||
cmdq_error(cmdq, "%s: %s", resolved, strerror(errno));
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
|
|
@ -97,7 +108,7 @@ cmd_load_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
pdata[psize++] = ch;
|
||||
}
|
||||
if (ferror(f)) {
|
||||
cmdq_error(cmdq, "%s: read error", path);
|
||||
cmdq_error(cmdq, "%s: read error", resolved);
|
||||
goto error;
|
||||
}
|
||||
if (pdata != NULL)
|
||||
|
|
@ -125,7 +136,7 @@ void
|
|||
cmd_load_buffer_callback(struct client *c, int closed, void *data)
|
||||
{
|
||||
const char *bufname = data;
|
||||
char *pdata, *cause;
|
||||
char *pdata, *cause, *saved;
|
||||
size_t psize;
|
||||
|
||||
if (!closed)
|
||||
|
|
@ -146,8 +157,13 @@ cmd_load_buffer_callback(struct client *c, int closed, void *data)
|
|||
|
||||
if (paste_set(pdata, psize, bufname, &cause) != 0) {
|
||||
/* No context so can't use server_client_msg_error. */
|
||||
if (~c->flags & CLIENT_UTF8) {
|
||||
saved = cause;
|
||||
cause = utf8_sanitize(saved);
|
||||
free(saved);
|
||||
}
|
||||
evbuffer_add_printf(c->stderr_data, "%s", cause);
|
||||
server_push_stderr(c);
|
||||
server_client_push_stderr(c);
|
||||
free(pdata);
|
||||
free(cause);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -27,49 +27,52 @@
|
|||
enum cmd_retval cmd_lock_server_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_lock_server_entry = {
|
||||
"lock-server", "lock",
|
||||
"", 0, 0,
|
||||
"",
|
||||
0,
|
||||
cmd_lock_server_exec
|
||||
.name = "lock-server",
|
||||
.alias = "lock",
|
||||
|
||||
.args = { "", 0, 0 },
|
||||
.usage = "",
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_lock_server_exec
|
||||
};
|
||||
|
||||
const struct cmd_entry cmd_lock_session_entry = {
|
||||
"lock-session", "locks",
|
||||
"t:", 0, 0,
|
||||
CMD_TARGET_SESSION_USAGE,
|
||||
0,
|
||||
cmd_lock_server_exec
|
||||
.name = "lock-session",
|
||||
.alias = "locks",
|
||||
|
||||
.args = { "t:", 0, 0 },
|
||||
.usage = CMD_TARGET_SESSION_USAGE,
|
||||
|
||||
.tflag = CMD_SESSION,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_lock_server_exec
|
||||
};
|
||||
|
||||
const struct cmd_entry cmd_lock_client_entry = {
|
||||
"lock-client", "lockc",
|
||||
"t:", 0, 0,
|
||||
CMD_TARGET_CLIENT_USAGE,
|
||||
0,
|
||||
cmd_lock_server_exec
|
||||
.name = "lock-client",
|
||||
.alias = "lockc",
|
||||
|
||||
.args = { "t:", 0, 0 },
|
||||
.usage = CMD_TARGET_CLIENT_USAGE,
|
||||
|
||||
.tflag = CMD_CLIENT,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_lock_server_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_lock_server_exec(struct cmd *self, unused struct cmd_q *cmdq)
|
||||
cmd_lock_server_exec(struct cmd *self, __unused struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct client *c;
|
||||
struct session *s;
|
||||
|
||||
if (self->entry == &cmd_lock_server_entry)
|
||||
server_lock();
|
||||
else if (self->entry == &cmd_lock_session_entry) {
|
||||
s = cmd_find_session(cmdq, args_get(args, 't'), 0);
|
||||
if (s == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
server_lock_session(s);
|
||||
} else {
|
||||
c = cmd_find_client(cmdq, args_get(args, 't'), 0);
|
||||
if (c == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
server_lock_client(c);
|
||||
}
|
||||
else if (self->entry == &cmd_lock_session_entry)
|
||||
server_lock_session(cmdq->state.tflag.s);
|
||||
else
|
||||
server_lock_client(cmdq->state.c);
|
||||
|
||||
recalculate_sizes();
|
||||
|
||||
return (CMD_RETURN_NORMAL);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -29,55 +29,63 @@
|
|||
enum cmd_retval cmd_move_window_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_move_window_entry = {
|
||||
"move-window", "movew",
|
||||
"adkrs:t:", 0, 0,
|
||||
"[-dkr] " CMD_SRCDST_WINDOW_USAGE,
|
||||
0,
|
||||
cmd_move_window_exec
|
||||
.name = "move-window",
|
||||
.alias = "movew",
|
||||
|
||||
.args = { "adkrs:t:", 0, 0 },
|
||||
.usage = "[-dkr] " CMD_SRCDST_WINDOW_USAGE,
|
||||
|
||||
.sflag = CMD_WINDOW,
|
||||
.tflag = CMD_MOVEW_R,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_move_window_exec
|
||||
};
|
||||
|
||||
const struct cmd_entry cmd_link_window_entry = {
|
||||
"link-window", "linkw",
|
||||
"adks:t:", 0, 0,
|
||||
"[-dk] " CMD_SRCDST_WINDOW_USAGE,
|
||||
0,
|
||||
cmd_move_window_exec
|
||||
.name = "link-window",
|
||||
.alias = "linkw",
|
||||
|
||||
.args = { "adks:t:", 0, 0 },
|
||||
.usage = "[-dk] " CMD_SRCDST_WINDOW_USAGE,
|
||||
|
||||
.sflag = CMD_WINDOW,
|
||||
.tflag = CMD_WINDOW_INDEX,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_move_window_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_move_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
#ifdef TMATE
|
||||
cmdq_error(cmdq, "move window is not supported with tmate");
|
||||
return (CMD_RETURN_ERROR);
|
||||
#else
|
||||
struct args *args = self->args;
|
||||
struct session *src, *dst, *s;
|
||||
struct winlink *wl;
|
||||
struct session *src = cmdq->state.sflag.s;
|
||||
struct session *dst = cmdq->state.tflag.s;
|
||||
struct winlink *wl = cmdq->state.sflag.wl;
|
||||
char *cause;
|
||||
int idx, kflag, dflag, sflag;
|
||||
int idx = cmdq->state.tflag.idx, kflag, dflag, sflag;
|
||||
|
||||
kflag = args_has(self->args, 'k');
|
||||
dflag = args_has(self->args, 'd');
|
||||
|
||||
if (args_has(args, 'r')) {
|
||||
s = cmd_find_session(cmdq, args_get(args, 't'), 0);
|
||||
if (s == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
||||
session_renumber_windows(s);
|
||||
session_renumber_windows(dst);
|
||||
recalculate_sizes();
|
||||
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
if ((wl = cmd_find_window(cmdq, args_get(args, 's'), &src)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
if ((idx = cmd_find_index(cmdq, args_get(args, 't'), &dst)) == -2)
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
||||
kflag = args_has(self->args, 'k');
|
||||
dflag = args_has(self->args, 'd');
|
||||
sflag = args_has(self->args, 's');
|
||||
|
||||
if (args_has(self->args, 'a')) {
|
||||
s = cmd_find_session(cmdq, args_get(args, 't'), 0);
|
||||
if (s == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
if ((idx = winlink_shuffle_up(s, s->curw)) == -1)
|
||||
if ((idx = winlink_shuffle_up(dst, dst->curw)) == -1)
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
|
|
@ -95,10 +103,11 @@ cmd_move_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
* session already has the correct winlink id to us, either
|
||||
* automatically or specified by -s.
|
||||
*/
|
||||
if (!sflag && options_get_number(&src->options, "renumber-windows"))
|
||||
if (!sflag && options_get_number(src->options, "renumber-windows"))
|
||||
session_renumber_windows(src);
|
||||
|
||||
recalculate_sizes();
|
||||
|
||||
return (CMD_RETURN_NORMAL);
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -36,44 +36,56 @@
|
|||
enum cmd_retval cmd_new_session_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_new_session_entry = {
|
||||
"new-session", "new",
|
||||
"Ac:dDEF:n:Ps:t:x:y:", 0, -1,
|
||||
"[-AdDEP] [-c start-directory] [-F format] [-n window-name] "
|
||||
"[-s session-name] " CMD_TARGET_SESSION_USAGE " [-x width] "
|
||||
"[-y height] [command]",
|
||||
CMD_STARTSERVER,
|
||||
cmd_new_session_exec
|
||||
.name = "new-session",
|
||||
.alias = "new",
|
||||
|
||||
.args = { "Ac:dDEF:n:Ps:t:x:y:", 0, -1 },
|
||||
.usage = "[-AdDEP] [-c start-directory] [-F format] [-n window-name] "
|
||||
"[-s session-name] " CMD_TARGET_SESSION_USAGE " [-x width] "
|
||||
"[-y height] [command]",
|
||||
|
||||
.tflag = CMD_SESSION_CANFAIL,
|
||||
|
||||
.flags = CMD_STARTSERVER,
|
||||
.exec = cmd_new_session_exec
|
||||
};
|
||||
|
||||
const struct cmd_entry cmd_has_session_entry = {
|
||||
"has-session", "has",
|
||||
"t:", 0, 0,
|
||||
CMD_TARGET_SESSION_USAGE,
|
||||
0,
|
||||
cmd_new_session_exec
|
||||
.name = "has-session",
|
||||
.alias = "has",
|
||||
|
||||
.args = { "t:", 0, 0 },
|
||||
.usage = CMD_TARGET_SESSION_USAGE,
|
||||
|
||||
.tflag = CMD_SESSION,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_new_session_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct client *c = cmdq->client, *c0;
|
||||
struct session *s, *groupwith;
|
||||
struct client *c = cmdq->client;
|
||||
struct session *s, *as;
|
||||
struct session *groupwith = cmdq->state.tflag.s;
|
||||
struct window *w;
|
||||
struct environ env;
|
||||
struct environ *env;
|
||||
struct termios tio, *tiop;
|
||||
const char *newname, *target, *update, *errstr, *template;
|
||||
const char *path;
|
||||
const char *path, *cwd, *to_free = NULL;
|
||||
char **argv, *cmd, *cause, *cp;
|
||||
int detached, already_attached, idx, cwd, fd = -1;
|
||||
int argc;
|
||||
int detached, already_attached, idx, argc;
|
||||
u_int sx, sy;
|
||||
struct format_tree *ft;
|
||||
struct environ_entry *envent;
|
||||
|
||||
if (self->entry == &cmd_has_session_entry) {
|
||||
if (cmd_find_session(cmdq, args_get(args, 't'), 0) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
/*
|
||||
* cmd_prepare() will fail if the session cannot be found,
|
||||
* hence always return success here.
|
||||
*/
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
|
|
@ -88,9 +100,16 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
cmdq_error(cmdq, "bad session name: %s", newname);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
if (session_find(newname) != NULL) {
|
||||
if ((as = session_find(newname)) != NULL) {
|
||||
if (args_has(args, 'A')) {
|
||||
return (cmd_attach_session(cmdq, newname,
|
||||
/*
|
||||
* This cmdq is now destined for
|
||||
* attach-session. Because attach-session
|
||||
* will have already been prepared, copy this
|
||||
* session into its tflag so it can be used.
|
||||
*/
|
||||
cmd_find_from_session(&cmdq->state.tflag, as);
|
||||
return (cmd_attach_session(cmdq,
|
||||
args_has(args, 'D'), 0, NULL,
|
||||
args_has(args, 'E')));
|
||||
}
|
||||
|
|
@ -99,11 +118,11 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
}
|
||||
}
|
||||
|
||||
target = args_get(args, 't');
|
||||
if (target != NULL) {
|
||||
groupwith = cmd_find_session(cmdq, target, 0);
|
||||
if (groupwith == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
if ((target = args_get(args, 't')) != NULL) {
|
||||
if (groupwith == NULL) {
|
||||
cmdq_error(cmdq, "no such session: %s", target);
|
||||
goto error;
|
||||
}
|
||||
} else
|
||||
groupwith = NULL;
|
||||
|
||||
|
|
@ -112,6 +131,9 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
if (c == NULL)
|
||||
detached = 1;
|
||||
|
||||
if (tmate_foreground)
|
||||
detached = 1;
|
||||
|
||||
/* Is this client already attached? */
|
||||
already_attached = 0;
|
||||
if (c != NULL && c->session != NULL)
|
||||
|
|
@ -119,31 +141,14 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
|
||||
/* Get the new session working directory. */
|
||||
if (args_has(args, 'c')) {
|
||||
ft = format_create();
|
||||
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), NULL, NULL,
|
||||
NULL);
|
||||
cp = format_expand(ft, args_get(args, 'c'));
|
||||
ft = format_create(cmdq, 0);
|
||||
format_defaults(ft, c, NULL, NULL, NULL);
|
||||
to_free = cwd = format_expand(ft, args_get(args, 'c'));
|
||||
format_free(ft);
|
||||
|
||||
if (cp != NULL && *cp != '\0') {
|
||||
fd = open(cp, O_RDONLY|O_DIRECTORY);
|
||||
free(cp);
|
||||
if (fd == -1) {
|
||||
cmdq_error(cmdq, "bad working directory: %s",
|
||||
strerror(errno));
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
} else if (cp != NULL)
|
||||
free(cp);
|
||||
cwd = fd;
|
||||
} else if (c != NULL && c->session == NULL)
|
||||
} else if (c != NULL && c->session == NULL && c->cwd != NULL)
|
||||
cwd = c->cwd;
|
||||
else if ((c0 = cmd_find_client(cmdq, NULL, 1)) != NULL)
|
||||
cwd = c0->session->cwd;
|
||||
else {
|
||||
fd = open(".", O_RDONLY);
|
||||
cwd = fd;
|
||||
}
|
||||
else
|
||||
cwd = ".";
|
||||
|
||||
/*
|
||||
* If this is a new client, check for nesting and save the termios
|
||||
|
|
@ -197,7 +202,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
goto error;
|
||||
}
|
||||
}
|
||||
if (sy > 0 && options_get_number(&global_s_options, "status"))
|
||||
if (sy > 0 && options_get_number(global_s_options, "status"))
|
||||
sy--;
|
||||
if (sx == 0)
|
||||
sx = 1;
|
||||
|
|
@ -207,11 +212,11 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
/* Figure out the command for the new window. */
|
||||
argc = -1;
|
||||
argv = NULL;
|
||||
if (target == NULL && args->argc != 0) {
|
||||
if (!args_has(args, 't') && args->argc != 0) {
|
||||
argc = args->argc;
|
||||
argv = args->argv;
|
||||
} else if (target == NULL) {
|
||||
cmd = options_get_string(&global_s_options, "default-command");
|
||||
} else if (groupwith == NULL) {
|
||||
cmd = options_get_string(global_s_options, "default-command");
|
||||
if (cmd != NULL && *cmd != '\0') {
|
||||
argc = 1;
|
||||
argv = &cmd;
|
||||
|
|
@ -223,36 +228,36 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
|
||||
path = NULL;
|
||||
if (c != NULL && c->session == NULL)
|
||||
envent = environ_find(&c->environ, "PATH");
|
||||
envent = environ_find(c->environ, "PATH");
|
||||
else
|
||||
envent = environ_find(&global_environ, "PATH");
|
||||
envent = environ_find(global_environ, "PATH");
|
||||
if (envent != NULL)
|
||||
path = envent->value;
|
||||
|
||||
/* Construct the environment. */
|
||||
environ_init(&env);
|
||||
env = environ_create();
|
||||
if (c != NULL && !args_has(args, 'E')) {
|
||||
update = options_get_string(&global_s_options,
|
||||
update = options_get_string(global_s_options,
|
||||
"update-environment");
|
||||
environ_update(update, &c->environ, &env);
|
||||
environ_update(update, c->environ, env);
|
||||
}
|
||||
|
||||
/* Create the new session. */
|
||||
idx = -1 - options_get_number(&global_s_options, "base-index");
|
||||
s = session_create(newname, argc, argv, path, cwd, &env, tiop, idx, sx,
|
||||
idx = -1 - options_get_number(global_s_options, "base-index");
|
||||
s = session_create(newname, argc, argv, path, cwd, env, tiop, idx, sx,
|
||||
sy, &cause);
|
||||
environ_free(env);
|
||||
if (s == NULL) {
|
||||
cmdq_error(cmdq, "create session failed: %s", cause);
|
||||
free(cause);
|
||||
goto error;
|
||||
}
|
||||
environ_free(&env);
|
||||
|
||||
/* Set the initial window name if one given. */
|
||||
if (argc >= 0 && args_has(args, 'n')) {
|
||||
w = s->curw->window;
|
||||
window_set_name(w, args_get(args, 'n'));
|
||||
options_set_number(&w->options, "automatic-rename", 0);
|
||||
options_set_number(w->options, "automatic-rename", 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -270,11 +275,13 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
* taking this session and needs to get MSG_READY and stay around.
|
||||
*/
|
||||
if (!detached) {
|
||||
if (!already_attached)
|
||||
server_write_ready(c);
|
||||
else if (c->session != NULL)
|
||||
if (!already_attached) {
|
||||
if (~c->flags & CLIENT_CONTROL)
|
||||
proc_send(c->peer, MSG_READY, -1, NULL, 0);
|
||||
} else if (c->session != NULL)
|
||||
c->last_session = c->session;
|
||||
c->session = s;
|
||||
server_client_set_key_table(c, NULL);
|
||||
status_timer_start(c);
|
||||
notify_attached_session_changed(c);
|
||||
session_update_activity(s, NULL);
|
||||
|
|
@ -296,9 +303,8 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
if ((template = args_get(args, 'F')) == NULL)
|
||||
template = NEW_SESSION_TEMPLATE;
|
||||
|
||||
ft = format_create();
|
||||
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, NULL,
|
||||
NULL);
|
||||
ft = format_create(cmdq, 0);
|
||||
format_defaults(ft, c, s, NULL, NULL);
|
||||
|
||||
cp = format_expand(ft, template);
|
||||
cmdq_print(cmdq, "%s", cp);
|
||||
|
|
@ -310,12 +316,12 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
if (!detached)
|
||||
cmdq->client_exit = 0;
|
||||
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
if (to_free != NULL)
|
||||
free((void *)to_free);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
|
||||
error:
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
if (to_free != NULL)
|
||||
free((void *)to_free);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -35,43 +35,43 @@
|
|||
enum cmd_retval cmd_new_window_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_new_window_entry = {
|
||||
"new-window", "neww",
|
||||
"ac:dF:kn:Pt:", 0, -1,
|
||||
"[-adkP] [-c start-directory] [-F format] [-n window-name] "
|
||||
CMD_TARGET_WINDOW_USAGE " [command]",
|
||||
0,
|
||||
cmd_new_window_exec
|
||||
.name = "new-window",
|
||||
.alias = "neww",
|
||||
|
||||
.args = { "ac:dF:kn:Pt:", 0, -1 },
|
||||
.usage = "[-adkP] [-c start-directory] [-F format] [-n window-name] "
|
||||
CMD_TARGET_WINDOW_USAGE " [command]",
|
||||
|
||||
.tflag = CMD_WINDOW_INDEX,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_new_window_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct session *s;
|
||||
struct winlink *wl;
|
||||
const char *cmd, *path, *template;
|
||||
struct session *s = cmdq->state.tflag.s;
|
||||
struct winlink *wl = cmdq->state.tflag.wl;
|
||||
struct client *c = cmdq->state.c;
|
||||
int idx = cmdq->state.tflag.idx;
|
||||
const char *cmd, *path, *template, *cwd, *to_free;
|
||||
char **argv, *cause, *cp;
|
||||
int argc, idx, detached, cwd, fd = -1;
|
||||
int argc, detached;
|
||||
struct format_tree *ft;
|
||||
struct environ_entry *envent;
|
||||
|
||||
if (args_has(args, 'a')) {
|
||||
wl = cmd_find_window(cmdq, args_get(args, 't'), &s);
|
||||
if (wl == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
if ((idx = winlink_shuffle_up(s, wl)) == -1) {
|
||||
cmdq_error(cmdq, "no free window indexes");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
} else {
|
||||
idx = cmd_find_index(cmdq, args_get(args, 't'), &s);
|
||||
if (idx == -2)
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
detached = args_has(args, 'd');
|
||||
|
||||
if (args->argc == 0) {
|
||||
cmd = options_get_string(&s->options, "default-command");
|
||||
cmd = options_get_string(s->options, "default-command");
|
||||
if (cmd != NULL && *cmd != '\0') {
|
||||
argc = 1;
|
||||
argv = (char **)&cmd;
|
||||
|
|
@ -86,30 +86,18 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
|
||||
path = NULL;
|
||||
if (cmdq->client != NULL && cmdq->client->session == NULL)
|
||||
envent = environ_find(&cmdq->client->environ, "PATH");
|
||||
envent = environ_find(cmdq->client->environ, "PATH");
|
||||
else
|
||||
envent = environ_find(&s->environ, "PATH");
|
||||
envent = environ_find(s->environ, "PATH");
|
||||
if (envent != NULL)
|
||||
path = envent->value;
|
||||
|
||||
to_free = NULL;
|
||||
if (args_has(args, 'c')) {
|
||||
ft = format_create();
|
||||
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, NULL,
|
||||
NULL);
|
||||
cp = format_expand(ft, args_get(args, 'c'));
|
||||
ft = format_create(cmdq, 0);
|
||||
format_defaults(ft, c, s, NULL, NULL);
|
||||
cwd = to_free = format_expand(ft, args_get(args, 'c'));
|
||||
format_free(ft);
|
||||
|
||||
if (cp != NULL && *cp != '\0') {
|
||||
fd = open(cp, O_RDONLY|O_DIRECTORY);
|
||||
free(cp);
|
||||
if (fd == -1) {
|
||||
cmdq_error(cmdq, "bad working directory: %s",
|
||||
strerror(errno));
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
} else if (cp != NULL)
|
||||
free(cp);
|
||||
cwd = fd;
|
||||
} else if (cmdq->client != NULL && cmdq->client->session == NULL)
|
||||
cwd = cmdq->client->cwd;
|
||||
else
|
||||
|
|
@ -136,7 +124,7 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
}
|
||||
|
||||
if (idx == -1)
|
||||
idx = -1 - options_get_number(&s->options, "base-index");
|
||||
idx = -1 - options_get_number(s->options, "base-index");
|
||||
wl = session_new(s, args_get(args, 'n'), argc, argv, path, cwd, idx,
|
||||
&cause);
|
||||
if (wl == NULL) {
|
||||
|
|
@ -154,9 +142,8 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
if ((template = args_get(args, 'F')) == NULL)
|
||||
template = NEW_WINDOW_TEMPLATE;
|
||||
|
||||
ft = format_create();
|
||||
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, wl,
|
||||
NULL);
|
||||
ft = format_create(cmdq, 0);
|
||||
format_defaults(ft, c, s, wl, NULL);
|
||||
|
||||
cp = format_expand(ft, template);
|
||||
cmdq_print(cmdq, "%s", cp);
|
||||
|
|
@ -165,12 +152,12 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
format_free(ft);
|
||||
}
|
||||
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
if (to_free != NULL)
|
||||
free((void *)to_free);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
|
||||
error:
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
if (to_free != NULL)
|
||||
free((void *)to_free);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -33,27 +33,29 @@ void cmd_paste_buffer_filter(struct window_pane *,
|
|||
const char *, size_t, const char *, int);
|
||||
|
||||
const struct cmd_entry cmd_paste_buffer_entry = {
|
||||
"paste-buffer", "pasteb",
|
||||
"db:prs:t:", 0, 0,
|
||||
"[-dpr] [-s separator] " CMD_BUFFER_USAGE " " CMD_TARGET_PANE_USAGE,
|
||||
0,
|
||||
cmd_paste_buffer_exec
|
||||
.name = "paste-buffer",
|
||||
.alias = "pasteb",
|
||||
|
||||
.args = { "db:prs:t:", 0, 0 },
|
||||
.usage = "[-dpr] [-s separator] " CMD_BUFFER_USAGE " "
|
||||
CMD_TARGET_PANE_USAGE,
|
||||
|
||||
.tflag = CMD_PANE,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_paste_buffer_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_paste_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct window_pane *wp;
|
||||
struct session *s;
|
||||
struct window_pane *wp = cmdq->state.tflag.wp;
|
||||
struct paste_buffer *pb;
|
||||
const char *sepstr, *bufname, *bufdata, *bufend, *line;
|
||||
size_t seplen, bufsize;
|
||||
int bracket = args_has(args, 'p');
|
||||
|
||||
if (cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
||||
bufname = NULL;
|
||||
if (args_has(args, 'b'))
|
||||
bufname = args_get(args, 'b');
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -37,29 +37,30 @@ enum cmd_retval cmd_pipe_pane_exec(struct cmd *, struct cmd_q *);
|
|||
void cmd_pipe_pane_error_callback(struct bufferevent *, short, void *);
|
||||
|
||||
const struct cmd_entry cmd_pipe_pane_entry = {
|
||||
"pipe-pane", "pipep",
|
||||
"ot:", 0, 1,
|
||||
"[-o] " CMD_TARGET_PANE_USAGE " [command]",
|
||||
0,
|
||||
cmd_pipe_pane_exec
|
||||
.name = "pipe-pane",
|
||||
.alias = "pipep",
|
||||
|
||||
.args = { "ot:", 0, 1 },
|
||||
.usage = "[-o] " CMD_TARGET_PANE_USAGE " [command]",
|
||||
|
||||
.tflag = CMD_PANE,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_pipe_pane_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_pipe_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct client *c;
|
||||
struct session *s;
|
||||
struct winlink *wl;
|
||||
struct window_pane *wp;
|
||||
struct client *c = cmdq->state.c;
|
||||
struct window_pane *wp = cmdq->state.tflag.wp;
|
||||
struct session *s = cmdq->state.tflag.s;
|
||||
struct winlink *wl = cmdq->state.tflag.wl;
|
||||
char *cmd;
|
||||
int old_fd, pipe_fd[2], null_fd;
|
||||
struct format_tree *ft;
|
||||
|
||||
if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
c = cmd_find_client(cmdq, NULL, 1);
|
||||
|
||||
/* Destroy the old pipe. */
|
||||
old_fd = wp->pipe_fd;
|
||||
if (wp->pipe_fd != -1) {
|
||||
|
|
@ -88,7 +89,7 @@ cmd_pipe_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
}
|
||||
|
||||
/* Expand the command. */
|
||||
ft = format_create();
|
||||
ft = format_create(cmdq, 0);
|
||||
format_defaults(ft, c, s, wl, wp);
|
||||
cmd = format_expand_time(ft, args->argv[0], time(NULL));
|
||||
format_free(ft);
|
||||
|
|
@ -141,8 +142,8 @@ cmd_pipe_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
}
|
||||
|
||||
void
|
||||
cmd_pipe_pane_error_callback(
|
||||
unused struct bufferevent *bufev, unused short what, void *data)
|
||||
cmd_pipe_pane_error_callback(__unused struct bufferevent *bufev,
|
||||
__unused short what, void *data)
|
||||
{
|
||||
struct window_pane *wp = data;
|
||||
|
||||
|
|
|
|||
75
cmd-queue.c
75
cmd-queue.c
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2013 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -24,8 +24,9 @@
|
|||
#include <time.h>
|
||||
|
||||
#include "tmux.h"
|
||||
#include "tmate.h"
|
||||
|
||||
enum cmd_retval cmdq_continue_one(struct cmd_q *);
|
||||
static enum cmd_retval cmdq_continue_one(struct cmd_q *);
|
||||
|
||||
/* Create new command queue. */
|
||||
struct cmd_q *
|
||||
|
|
@ -44,6 +45,9 @@ cmdq_new(struct client *c)
|
|||
cmdq->item = NULL;
|
||||
cmdq->cmd = NULL;
|
||||
|
||||
cmd_find_clear_state(&cmdq->current, NULL, 0);
|
||||
cmdq->parent = NULL;
|
||||
|
||||
return (cmdq);
|
||||
}
|
||||
|
||||
|
|
@ -69,22 +73,32 @@ cmdq_print(struct cmd_q *cmdq, const char *fmt, ...)
|
|||
struct client *c = cmdq->client;
|
||||
struct window *w;
|
||||
va_list ap;
|
||||
char *tmp, *msg;
|
||||
|
||||
va_start(ap, fmt);
|
||||
|
||||
if (c == NULL)
|
||||
/* nothing */;
|
||||
else if (c->session == NULL || (c->flags & CLIENT_CONTROL)) {
|
||||
evbuffer_add_vprintf(c->stdout_data, fmt, ap);
|
||||
|
||||
if (~c->flags & CLIENT_UTF8) {
|
||||
vasprintf(&tmp, fmt, ap);
|
||||
msg = utf8_sanitize(tmp);
|
||||
free(tmp);
|
||||
evbuffer_add(c->stdout_data, msg, strlen(msg));
|
||||
free(msg);
|
||||
} else
|
||||
evbuffer_add_vprintf(c->stdout_data, fmt, ap);
|
||||
evbuffer_add(c->stdout_data, "\n", 1);
|
||||
server_push_stdout(c);
|
||||
server_client_push_stdout(c);
|
||||
} else {
|
||||
w = c->session->curw->window;
|
||||
if (w->active->mode != &window_copy_mode) {
|
||||
window_pane_reset_mode(w->active);
|
||||
window_pane_set_mode(w->active, &window_copy_mode);
|
||||
window_copy_init_for_output(w->active);
|
||||
#ifdef TMATE
|
||||
tmate_sync_copy_mode(w->active);
|
||||
#endif
|
||||
}
|
||||
window_copy_vadd(w->active, fmt, ap);
|
||||
}
|
||||
|
|
@ -101,18 +115,31 @@ cmdq_error(struct cmd_q *cmdq, const char *fmt, ...)
|
|||
va_list ap;
|
||||
char *msg;
|
||||
size_t msglen;
|
||||
char *tmp;
|
||||
|
||||
va_start(ap, fmt);
|
||||
msglen = xvasprintf(&msg, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (c == NULL)
|
||||
#ifdef TMATE
|
||||
if (cmd->file && cmd->line)
|
||||
cfg_add_cause("%s:%u: %s", cmd->file, cmd->line, msg);
|
||||
else
|
||||
cfg_add_cause("%s", msg);
|
||||
#else
|
||||
cfg_add_cause("%s:%u: %s", cmd->file, cmd->line, msg);
|
||||
#endif
|
||||
else if (c->session == NULL || (c->flags & CLIENT_CONTROL)) {
|
||||
if (~c->flags & CLIENT_UTF8) {
|
||||
tmp = msg;
|
||||
msg = utf8_sanitize(tmp);
|
||||
free(tmp);
|
||||
msglen = strlen(msg);
|
||||
}
|
||||
evbuffer_add(c->stderr_data, msg, msglen);
|
||||
evbuffer_add(c->stderr_data, "\n", 1);
|
||||
|
||||
server_push_stderr(c);
|
||||
server_client_push_stderr(c);
|
||||
c->retval = 1;
|
||||
} else {
|
||||
*msg = toupper((u_char) *msg);
|
||||
|
|
@ -133,7 +160,7 @@ cmdq_guard(struct cmd_q *cmdq, const char *guard, int flags)
|
|||
|
||||
evbuffer_add_printf(c->stdout_data, "%%%s %ld %u %d\n", guard,
|
||||
(long) cmdq->time, cmdq->number, flags);
|
||||
server_push_stdout(c);
|
||||
server_client_push_stdout(c);
|
||||
}
|
||||
|
||||
/* Add command list to queue and begin processing if needed. */
|
||||
|
|
@ -166,36 +193,47 @@ cmdq_append(struct cmd_q *cmdq, struct cmd_list *cmdlist, struct mouse_event *m)
|
|||
}
|
||||
|
||||
/* Process one command. */
|
||||
enum cmd_retval
|
||||
static enum cmd_retval
|
||||
cmdq_continue_one(struct cmd_q *cmdq)
|
||||
{
|
||||
struct cmd *cmd = cmdq->cmd;
|
||||
enum cmd_retval retval;
|
||||
char tmp[1024];
|
||||
char *tmp;
|
||||
int flags = !!(cmd->flags & CMD_CONTROL);
|
||||
|
||||
cmd_print(cmd, tmp, sizeof tmp);
|
||||
#ifdef TMATE
|
||||
if (tmate_should_replicate_cmd(cmd->entry))
|
||||
tmate_exec_cmd(cmd);
|
||||
#endif
|
||||
|
||||
tmp = cmd_print(cmd);
|
||||
log_debug("cmdq %p: %s", cmdq, tmp);
|
||||
free(tmp);
|
||||
|
||||
cmdq->time = time(NULL);
|
||||
cmdq->number++;
|
||||
|
||||
cmdq_guard(cmdq, "begin", flags);
|
||||
|
||||
if (cmd_prepare_state(cmd, cmdq, NULL) != 0)
|
||||
goto error;
|
||||
retval = cmd->entry->exec(cmd, cmdq);
|
||||
|
||||
if (retval == CMD_RETURN_ERROR)
|
||||
cmdq_guard(cmdq, "error", flags);
|
||||
else
|
||||
cmdq_guard(cmdq, "end", flags);
|
||||
goto error;
|
||||
|
||||
cmdq_guard(cmdq, "end", flags);
|
||||
return (retval);
|
||||
|
||||
error:
|
||||
cmdq_guard(cmdq, "error", flags);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
/* Continue processing command queue. Returns 1 if finishes empty. */
|
||||
int
|
||||
cmdq_continue(struct cmd_q *cmdq)
|
||||
{
|
||||
struct client *c = cmdq->client;
|
||||
struct client *c = cmdq->client;
|
||||
struct cmd_q_item *next;
|
||||
enum cmd_retval retval;
|
||||
int empty;
|
||||
|
|
@ -203,8 +241,8 @@ cmdq_continue(struct cmd_q *cmdq)
|
|||
cmdq->references++;
|
||||
notify_disable();
|
||||
|
||||
log_debug("continuing cmdq %p: flags=%#x, client=%d", cmdq, cmdq->flags,
|
||||
c != NULL ? c->ibuf.fd : -1);
|
||||
log_debug("continuing cmdq %p: flags %#x, client %p", cmdq, cmdq->flags,
|
||||
c);
|
||||
|
||||
empty = TAILQ_EMPTY(&cmdq->queue);
|
||||
if (empty)
|
||||
|
|
@ -267,3 +305,4 @@ cmdq_flush(struct cmd_q *cmdq)
|
|||
}
|
||||
cmdq->item = NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -27,24 +27,26 @@
|
|||
enum cmd_retval cmd_refresh_client_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_refresh_client_entry = {
|
||||
"refresh-client", "refresh",
|
||||
"C:St:", 0, 0,
|
||||
"[-S] [-C size] " CMD_TARGET_CLIENT_USAGE,
|
||||
0,
|
||||
cmd_refresh_client_exec
|
||||
.name = "refresh-client",
|
||||
.alias = "refresh",
|
||||
|
||||
.args = { "C:St:", 0, 0 },
|
||||
.usage = "[-S] [-C size] " CMD_TARGET_CLIENT_USAGE,
|
||||
|
||||
.tflag = CMD_CLIENT,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_refresh_client_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_refresh_client_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct client *c;
|
||||
struct client *c = cmdq->state.c;
|
||||
const char *size;
|
||||
u_int w, h;
|
||||
|
||||
if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
||||
if (args_has(args, 'C')) {
|
||||
if ((size = args_get(args, 'C')) == NULL) {
|
||||
cmdq_error(cmdq, "missing size");
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -29,18 +29,23 @@
|
|||
enum cmd_retval cmd_rename_session_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_rename_session_entry = {
|
||||
"rename-session", "rename",
|
||||
"t:", 1, 1,
|
||||
CMD_TARGET_SESSION_USAGE " new-name",
|
||||
0,
|
||||
cmd_rename_session_exec
|
||||
.name = "rename-session",
|
||||
.alias = "rename",
|
||||
|
||||
.args = { "t:", 1, 1 },
|
||||
.usage = CMD_TARGET_SESSION_USAGE " new-name",
|
||||
|
||||
.tflag = CMD_SESSION,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_rename_session_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_rename_session_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct session *s;
|
||||
struct session *s = cmdq->state.tflag.s;
|
||||
const char *newname;
|
||||
|
||||
newname = args->argv[0];
|
||||
|
|
@ -53,9 +58,6 @@ cmd_rename_session_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
if ((s = cmd_find_session(cmdq, args_get(args, 't'), 0)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
||||
RB_REMOVE(sessions, &sessions, s);
|
||||
free(s->name);
|
||||
s->name = xstrdup(newname);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -29,25 +29,26 @@
|
|||
enum cmd_retval cmd_rename_window_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_rename_window_entry = {
|
||||
"rename-window", "renamew",
|
||||
"t:", 1, 1,
|
||||
CMD_TARGET_WINDOW_USAGE " new-name",
|
||||
0,
|
||||
cmd_rename_window_exec
|
||||
.name = "rename-window",
|
||||
.alias = "renamew",
|
||||
|
||||
.args = { "t:", 1, 1 },
|
||||
.usage = CMD_TARGET_WINDOW_USAGE " new-name",
|
||||
|
||||
.tflag = CMD_WINDOW,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_rename_window_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_rename_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct session *s;
|
||||
struct winlink *wl;
|
||||
|
||||
if ((wl = cmd_find_window(cmdq, args_get(args, 't'), &s)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
struct winlink *wl = cmdq->state.tflag.wl;
|
||||
|
||||
window_set_name(wl->window, args->argv[0]);
|
||||
options_set_number(&wl->window->options, "automatic-rename", 0);
|
||||
options_set_number(wl->window->options, "automatic-rename", 0);
|
||||
|
||||
server_status_window(wl->window);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -31,25 +31,30 @@ enum cmd_retval cmd_resize_pane_exec(struct cmd *, struct cmd_q *);
|
|||
void cmd_resize_pane_mouse_update(struct client *, struct mouse_event *);
|
||||
|
||||
const struct cmd_entry cmd_resize_pane_entry = {
|
||||
"resize-pane", "resizep",
|
||||
"DLMRt:Ux:y:Z", 0, 1,
|
||||
"[-DLMRUZ] [-x width] [-y height] " CMD_TARGET_PANE_USAGE
|
||||
" [adjustment]",
|
||||
0,
|
||||
cmd_resize_pane_exec
|
||||
.name = "resize-pane",
|
||||
.alias = "resizep",
|
||||
|
||||
.args = { "DLMRt:Ux:y:Z", 0, 1 },
|
||||
.usage = "[-DLMRUZ] [-x width] [-y height] " CMD_TARGET_PANE_USAGE " "
|
||||
"[adjustment]",
|
||||
|
||||
.tflag = CMD_PANE,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_resize_pane_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_resize_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct window_pane *wp = cmdq->state.tflag.wp;
|
||||
struct winlink *wl = cmdq->state.tflag.wl;
|
||||
struct window *w = wl->window;
|
||||
struct client *c = cmdq->client;
|
||||
struct session *s;
|
||||
struct winlink *wl;
|
||||
struct window *w;
|
||||
struct session *s = cmdq->state.tflag.s;
|
||||
const char *errstr;
|
||||
char *cause;
|
||||
struct window_pane *wp;
|
||||
u_int adjust;
|
||||
int x, y;
|
||||
|
||||
|
|
@ -63,10 +68,6 @@ cmd_resize_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), NULL, &wp)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
w = wl->window;
|
||||
|
||||
if (args_has(args, 'Z')) {
|
||||
if (w->flags & WINDOW_ZOOMED)
|
||||
window_unzoom(w);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
* Copyright (c) 2011 Marcel P. Partap <mpartap@gmx.net>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
|
|
@ -31,31 +31,32 @@
|
|||
enum cmd_retval cmd_respawn_pane_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_respawn_pane_entry = {
|
||||
"respawn-pane", "respawnp",
|
||||
"kt:", 0, -1,
|
||||
"[-k] " CMD_TARGET_PANE_USAGE " [command]",
|
||||
0,
|
||||
cmd_respawn_pane_exec
|
||||
.name = "respawn-pane",
|
||||
.alias = "respawnp",
|
||||
|
||||
.args = { "kt:", 0, -1 },
|
||||
.usage = "[-k] " CMD_TARGET_PANE_USAGE " [command]",
|
||||
|
||||
.tflag = CMD_PANE,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_respawn_pane_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_respawn_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct winlink *wl;
|
||||
struct window *w;
|
||||
struct window_pane *wp;
|
||||
struct session *s;
|
||||
struct environ env;
|
||||
struct winlink *wl = cmdq->state.tflag.wl;
|
||||
struct window *w = wl->window;
|
||||
struct window_pane *wp = cmdq->state.tflag.wp;
|
||||
struct session *s = cmdq->state.tflag.s;
|
||||
struct environ *env;
|
||||
const char *path;
|
||||
char *cause;
|
||||
u_int idx;
|
||||
struct environ_entry *envent;
|
||||
|
||||
if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
w = wl->window;
|
||||
|
||||
if (!args_has(self->args, 'k') && wp->fd != -1) {
|
||||
if (window_pane_index(wp, &idx) != 0)
|
||||
fatalx("index not found");
|
||||
|
|
@ -64,10 +65,10 @@ cmd_respawn_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
environ_init(&env);
|
||||
environ_copy(&global_environ, &env);
|
||||
environ_copy(&s->environ, &env);
|
||||
server_fill_environ(s, &env);
|
||||
env = environ_create();
|
||||
environ_copy(global_environ, env);
|
||||
environ_copy(s->environ, env);
|
||||
server_fill_environ(s, env);
|
||||
|
||||
window_pane_reset_mode(wp);
|
||||
screen_reinit(&wp->base);
|
||||
|
|
@ -75,22 +76,22 @@ cmd_respawn_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
|
||||
path = NULL;
|
||||
if (cmdq->client != NULL && cmdq->client->session == NULL)
|
||||
envent = environ_find(&cmdq->client->environ, "PATH");
|
||||
envent = environ_find(cmdq->client->environ, "PATH");
|
||||
else
|
||||
envent = environ_find(&s->environ, "PATH");
|
||||
envent = environ_find(s->environ, "PATH");
|
||||
if (envent != NULL)
|
||||
path = envent->value;
|
||||
|
||||
if (window_pane_spawn(wp, args->argc, args->argv, path, NULL, -1, &env,
|
||||
if (window_pane_spawn(wp, args->argc, args->argv, path, NULL, NULL, env,
|
||||
s->tio, &cause) != 0) {
|
||||
cmdq_error(cmdq, "respawn pane failed: %s", cause);
|
||||
free(cause);
|
||||
environ_free(&env);
|
||||
environ_free(env);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
wp->flags |= PANE_REDRAW;
|
||||
server_status_window(w);
|
||||
|
||||
environ_free(&env);
|
||||
environ_free(env);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -30,44 +30,45 @@
|
|||
enum cmd_retval cmd_respawn_window_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_respawn_window_entry = {
|
||||
"respawn-window", "respawnw",
|
||||
"kt:", 0, -1,
|
||||
"[-k] " CMD_TARGET_WINDOW_USAGE " [command]",
|
||||
0,
|
||||
cmd_respawn_window_exec
|
||||
.name = "respawn-window",
|
||||
.alias = "respawnw",
|
||||
|
||||
.args = { "kt:", 0, -1 },
|
||||
.usage = "[-k] " CMD_TARGET_WINDOW_USAGE " [command]",
|
||||
|
||||
.tflag = CMD_WINDOW,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_respawn_window_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_respawn_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct winlink *wl;
|
||||
struct window *w;
|
||||
struct session *s = cmdq->state.tflag.s;
|
||||
struct winlink *wl = cmdq->state.tflag.wl;
|
||||
struct window *w = wl->window;
|
||||
struct window_pane *wp;
|
||||
struct session *s;
|
||||
struct environ env;
|
||||
struct environ *env;
|
||||
const char *path;
|
||||
char *cause;
|
||||
struct environ_entry *envent;
|
||||
|
||||
if ((wl = cmd_find_window(cmdq, args_get(args, 't'), &s)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
w = wl->window;
|
||||
|
||||
if (!args_has(self->args, 'k')) {
|
||||
TAILQ_FOREACH(wp, &w->panes, entry) {
|
||||
if (wp->fd == -1)
|
||||
continue;
|
||||
cmdq_error(cmdq,
|
||||
"window still active: %s:%d", s->name, wl->idx);
|
||||
cmdq_error(cmdq, "window still active: %s:%d", s->name,
|
||||
wl->idx);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
environ_init(&env);
|
||||
environ_copy(&global_environ, &env);
|
||||
environ_copy(&s->environ, &env);
|
||||
server_fill_environ(s, &env);
|
||||
env = environ_create();
|
||||
environ_copy(global_environ, env);
|
||||
environ_copy(s->environ, env);
|
||||
server_fill_environ(s, env);
|
||||
|
||||
wp = TAILQ_FIRST(&w->panes);
|
||||
TAILQ_REMOVE(&w->panes, wp, entry);
|
||||
|
|
@ -78,18 +79,18 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
|
||||
path = NULL;
|
||||
if (cmdq->client != NULL && cmdq->client->session == NULL)
|
||||
envent = environ_find(&cmdq->client->environ, "PATH");
|
||||
envent = environ_find(cmdq->client->environ, "PATH");
|
||||
else
|
||||
envent = environ_find(&s->environ, "PATH");
|
||||
envent = environ_find(s->environ, "PATH");
|
||||
if (envent != NULL)
|
||||
path = envent->value;
|
||||
|
||||
if (window_pane_spawn(wp, args->argc, args->argv, path, NULL, -1, &env,
|
||||
if (window_pane_spawn(wp, args->argc, args->argv, path, NULL, NULL, env,
|
||||
s->tio, &cause) != 0) {
|
||||
cmdq_error(cmdq, "respawn window failed: %s", cause);
|
||||
free(cause);
|
||||
environ_free(&env);
|
||||
server_destroy_pane(wp);
|
||||
environ_free(env);
|
||||
server_destroy_pane(wp, 0);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
layout_init(w, wp);
|
||||
|
|
@ -101,6 +102,6 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
recalculate_sizes();
|
||||
server_redraw_window(w);
|
||||
|
||||
environ_free(&env);
|
||||
environ_free(env);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -27,27 +27,27 @@
|
|||
enum cmd_retval cmd_rotate_window_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_rotate_window_entry = {
|
||||
"rotate-window", "rotatew",
|
||||
"Dt:U", 0, 0,
|
||||
"[-DU] " CMD_TARGET_WINDOW_USAGE,
|
||||
0,
|
||||
cmd_rotate_window_exec
|
||||
.name = "rotate-window",
|
||||
.alias = "rotatew",
|
||||
|
||||
.args = { "Dt:U", 0, 0 },
|
||||
.usage = "[-DU] " CMD_TARGET_WINDOW_USAGE,
|
||||
|
||||
.tflag = CMD_WINDOW,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_rotate_window_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_rotate_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct winlink *wl;
|
||||
struct window *w;
|
||||
struct winlink *wl = cmdq->state.tflag.wl;
|
||||
struct window *w = wl->window;
|
||||
struct window_pane *wp, *wp2;
|
||||
struct layout_cell *lc;
|
||||
u_int sx, sy, xoff, yoff;
|
||||
|
||||
if ((wl = cmd_find_window(cmdq, args_get(args, 't'), NULL)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
w = wl->window;
|
||||
|
||||
if (args_has(self->args, 'D')) {
|
||||
wp = TAILQ_LAST(&w->panes, window_panes);
|
||||
TAILQ_REMOVE(&w->panes, wp, entry);
|
||||
|
|
|
|||
|
|
@ -36,11 +36,16 @@ void cmd_run_shell_free(void *);
|
|||
void cmd_run_shell_print(struct job *, const char *);
|
||||
|
||||
const struct cmd_entry cmd_run_shell_entry = {
|
||||
"run-shell", "run",
|
||||
"bt:", 1, 1,
|
||||
"[-b] " CMD_TARGET_PANE_USAGE " shell-command",
|
||||
0,
|
||||
cmd_run_shell_exec
|
||||
.name = "run-shell",
|
||||
.alias = "run",
|
||||
|
||||
.args = { "bt:", 1, 1 },
|
||||
.usage = "[-b] " CMD_TARGET_PANE_USAGE " shell-command",
|
||||
|
||||
.tflag = CMD_PANE_CANFAIL,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_run_shell_exec
|
||||
};
|
||||
|
||||
struct cmd_run_shell_data {
|
||||
|
|
@ -75,33 +80,20 @@ cmd_run_shell_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
struct args *args = self->args;
|
||||
struct cmd_run_shell_data *cdata;
|
||||
char *shellcmd;
|
||||
struct client *c;
|
||||
struct session *s = NULL;
|
||||
struct winlink *wl = NULL;
|
||||
struct window_pane *wp = NULL;
|
||||
struct session *s = cmdq->state.tflag.s;
|
||||
struct winlink *wl = cmdq->state.tflag.wl;
|
||||
struct window_pane *wp = cmdq->state.tflag.wp;
|
||||
struct format_tree *ft;
|
||||
int cwd;
|
||||
const char *cwd;
|
||||
|
||||
if (args_has(args, 't')) {
|
||||
wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp);
|
||||
cwd = wp->cwd;
|
||||
} else {
|
||||
c = cmd_find_client(cmdq, NULL, 1);
|
||||
if (c != NULL && c->session != NULL) {
|
||||
s = c->session;
|
||||
wl = s->curw;
|
||||
wp = wl->window->active;
|
||||
}
|
||||
if (cmdq->client != NULL && cmdq->client->session == NULL)
|
||||
cwd = cmdq->client->cwd;
|
||||
else if (s != NULL)
|
||||
cwd = s->cwd;
|
||||
else
|
||||
cwd = -1;
|
||||
}
|
||||
|
||||
ft = format_create();
|
||||
format_defaults(ft, NULL, s, wl, wp);
|
||||
if (cmdq->client != NULL && cmdq->client->session == NULL)
|
||||
cwd = cmdq->client->cwd;
|
||||
else if (s != NULL)
|
||||
cwd = s->cwd;
|
||||
else
|
||||
cwd = NULL;
|
||||
ft = format_create(cmdq, 0);
|
||||
format_defaults(ft, cmdq->state.c, s, wl, wp);
|
||||
shellcmd = format_expand(ft, args->argv[0]);
|
||||
format_free(ft);
|
||||
|
||||
|
|
|
|||
|
|
@ -34,19 +34,25 @@
|
|||
enum cmd_retval cmd_save_buffer_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_save_buffer_entry = {
|
||||
"save-buffer", "saveb",
|
||||
"ab:", 1, 1,
|
||||
"[-a] " CMD_BUFFER_USAGE " path",
|
||||
0,
|
||||
cmd_save_buffer_exec
|
||||
.name = "save-buffer",
|
||||
.alias = "saveb",
|
||||
|
||||
.args = { "ab:", 1, 1 },
|
||||
.usage = "[-a] " CMD_BUFFER_USAGE " path",
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_save_buffer_exec
|
||||
};
|
||||
|
||||
const struct cmd_entry cmd_show_buffer_entry = {
|
||||
"show-buffer", "showb",
|
||||
"b:", 0, 0,
|
||||
CMD_BUFFER_USAGE,
|
||||
0,
|
||||
cmd_save_buffer_exec
|
||||
.name = "show-buffer",
|
||||
.alias = "showb",
|
||||
|
||||
.args = { "b:", 0, 0 },
|
||||
.usage = CMD_BUFFER_USAGE,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_save_buffer_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
|
|
@ -56,10 +62,10 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
struct client *c = cmdq->client;
|
||||
struct session *s;
|
||||
struct paste_buffer *pb;
|
||||
const char *path, *bufname, *bufdata, *start, *end;
|
||||
char *msg;
|
||||
const char *path, *bufname, *bufdata, *start, *end, *cwd;
|
||||
const char *flags;
|
||||
char *msg, *file, resolved[PATH_MAX];
|
||||
size_t size, used, msglen, bufsize;
|
||||
int cwd, fd;
|
||||
FILE *f;
|
||||
|
||||
if (!args_has(args, 'b')) {
|
||||
|
|
@ -91,31 +97,35 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
goto do_print;
|
||||
}
|
||||
|
||||
if (c != NULL && c->session == NULL)
|
||||
if (c != NULL && c->session == NULL && c->cwd != NULL)
|
||||
cwd = c->cwd;
|
||||
else if ((s = cmd_find_current(cmdq)) != NULL)
|
||||
else if ((s = c->session) != NULL && s->cwd != NULL)
|
||||
cwd = s->cwd;
|
||||
else
|
||||
cwd = AT_FDCWD;
|
||||
cwd = ".";
|
||||
|
||||
f = NULL;
|
||||
if (args_has(self->args, 'a')) {
|
||||
fd = openat(cwd, path, O_CREAT|O_RDWR|O_APPEND, 0600);
|
||||
if (fd != -1)
|
||||
f = fdopen(fd, "ab");
|
||||
} else {
|
||||
fd = openat(cwd, path, O_CREAT|O_RDWR|O_TRUNC, 0600);
|
||||
if (fd != -1)
|
||||
f = fdopen(fd, "wb");
|
||||
}
|
||||
if (f == NULL) {
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
cmdq_error(cmdq, "%s: %s", path, strerror(errno));
|
||||
flags = "wb";
|
||||
if (args_has(self->args, 'a'))
|
||||
flags = "ab";
|
||||
|
||||
if (*path == '/')
|
||||
file = xstrdup(path);
|
||||
else
|
||||
xasprintf(&file, "%s/%s", cwd, path);
|
||||
if (realpath(file, resolved) == NULL &&
|
||||
strlcpy(resolved, file, sizeof resolved) >= sizeof resolved) {
|
||||
cmdq_error(cmdq, "%s: %s", file, strerror(ENAMETOOLONG));
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
f = fopen(resolved, flags);
|
||||
free(file);
|
||||
if (f == NULL) {
|
||||
cmdq_error(cmdq, "%s: %s", resolved, strerror(errno));
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
if (fwrite(bufdata, 1, bufsize, f) != bufsize) {
|
||||
cmdq_error(cmdq, "%s: fwrite error", path);
|
||||
cmdq_error(cmdq, "%s: write error", resolved);
|
||||
fclose(f);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
|
@ -125,7 +135,7 @@ cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
|
||||
do_stdout:
|
||||
evbuffer_add(c->stdout_data, bufdata, bufsize);
|
||||
server_push_stdout(c);
|
||||
server_client_push_stdout(c);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
|
||||
do_print:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -29,43 +29,55 @@
|
|||
enum cmd_retval cmd_select_layout_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_select_layout_entry = {
|
||||
"select-layout", "selectl",
|
||||
"nopt:", 0, 1,
|
||||
"[-nop] " CMD_TARGET_WINDOW_USAGE " [layout-name]",
|
||||
0,
|
||||
cmd_select_layout_exec
|
||||
.name = "select-layout",
|
||||
.alias = "selectl",
|
||||
|
||||
.args = { "nopt:", 0, 1 },
|
||||
.usage = "[-nop] " CMD_TARGET_WINDOW_USAGE " [layout-name]",
|
||||
|
||||
.tflag = CMD_WINDOW,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_select_layout_exec
|
||||
};
|
||||
|
||||
const struct cmd_entry cmd_next_layout_entry = {
|
||||
"next-layout", "nextl",
|
||||
"t:", 0, 0,
|
||||
CMD_TARGET_WINDOW_USAGE,
|
||||
0,
|
||||
cmd_select_layout_exec
|
||||
.name = "next-layout",
|
||||
.alias = "nextl",
|
||||
|
||||
.args = { "t:", 0, 0 },
|
||||
.usage = CMD_TARGET_WINDOW_USAGE,
|
||||
|
||||
.tflag = CMD_WINDOW,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_select_layout_exec
|
||||
};
|
||||
|
||||
const struct cmd_entry cmd_previous_layout_entry = {
|
||||
"previous-layout", "prevl",
|
||||
"t:", 0, 0,
|
||||
CMD_TARGET_WINDOW_USAGE,
|
||||
0,
|
||||
cmd_select_layout_exec
|
||||
.name = "previous-layout",
|
||||
.alias = "prevl",
|
||||
|
||||
.args = { "t:", 0, 0 },
|
||||
.usage = CMD_TARGET_WINDOW_USAGE,
|
||||
|
||||
.tflag = CMD_WINDOW,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_select_layout_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_select_layout_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct winlink *wl;
|
||||
struct winlink *wl = cmdq->state.tflag.wl;
|
||||
struct window *w;
|
||||
const char *layoutname;
|
||||
char *oldlayout;
|
||||
int next, previous, layout;
|
||||
|
||||
if ((wl = cmd_find_window(cmdq, args_get(args, 't'), NULL)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
w = wl->window;
|
||||
|
||||
server_unzoom_window(w);
|
||||
|
||||
next = self->entry == &cmd_next_layout_entry;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -27,38 +27,44 @@
|
|||
enum cmd_retval cmd_select_pane_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_select_pane_entry = {
|
||||
"select-pane", "selectp",
|
||||
"DdegLlMmP:Rt:U", 0, 0,
|
||||
"[-DdegLlMmRU] [-P style] " CMD_TARGET_PANE_USAGE,
|
||||
0,
|
||||
cmd_select_pane_exec
|
||||
.name = "select-pane",
|
||||
.alias = "selectp",
|
||||
|
||||
.args = { "DdegLlMmP:Rt:U", 0, 0 },
|
||||
.usage = "[-DdegLlMmRU] [-P style] " CMD_TARGET_PANE_USAGE,
|
||||
|
||||
.tflag = CMD_PANE,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_select_pane_exec
|
||||
};
|
||||
|
||||
const struct cmd_entry cmd_last_pane_entry = {
|
||||
"last-pane", "lastp",
|
||||
"det:", 0, 0,
|
||||
"[-de] " CMD_TARGET_WINDOW_USAGE,
|
||||
0,
|
||||
cmd_select_pane_exec
|
||||
.name = "last-pane",
|
||||
.alias = "lastp",
|
||||
|
||||
.args = { "det:", 0, 0 },
|
||||
.usage = "[-de] " CMD_TARGET_WINDOW_USAGE,
|
||||
|
||||
.tflag = CMD_WINDOW,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_select_pane_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_select_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct winlink *wl;
|
||||
struct window *w;
|
||||
struct session *s;
|
||||
struct window_pane *wp, *lastwp, *markedwp;
|
||||
struct winlink *wl = cmdq->state.tflag.wl;
|
||||
struct window *w = wl->window;
|
||||
struct session *s = cmdq->state.tflag.s;
|
||||
struct window_pane *wp = cmdq->state.tflag.wp, *lastwp, *markedwp;
|
||||
const char *style;
|
||||
|
||||
if (self->entry == &cmd_last_pane_entry || args_has(args, 'l')) {
|
||||
wl = cmd_find_window(cmdq, args_get(args, 't'), NULL);
|
||||
if (wl == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
w = wl->window;
|
||||
|
||||
if (w->last == NULL) {
|
||||
if (wl->window->last == NULL) {
|
||||
cmdq_error(cmdq, "no last pane");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
|
@ -79,20 +85,16 @@ cmd_select_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
w = wl->window;
|
||||
|
||||
if (args_has(args, 'm') || args_has(args, 'M')) {
|
||||
if (args_has(args, 'm') && !window_pane_visible(wp))
|
||||
return (CMD_RETURN_NORMAL);
|
||||
lastwp = marked_window_pane;
|
||||
lastwp = marked_pane.wp;
|
||||
|
||||
if (args_has(args, 'M') || server_is_marked(s, wl, wp))
|
||||
server_clear_marked();
|
||||
else
|
||||
server_set_marked(s, wl, wp);
|
||||
markedwp = marked_window_pane;
|
||||
markedwp = marked_pane.wp;
|
||||
|
||||
if (lastwp != NULL) {
|
||||
server_redraw_window_borders(lastwp->window);
|
||||
|
|
@ -120,14 +122,19 @@ cmd_select_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
if (args_has(self->args, 'L'))
|
||||
if (args_has(self->args, 'L')) {
|
||||
server_unzoom_window(wp->window);
|
||||
wp = window_pane_find_left(wp);
|
||||
else if (args_has(self->args, 'R'))
|
||||
} else if (args_has(self->args, 'R')) {
|
||||
server_unzoom_window(wp->window);
|
||||
wp = window_pane_find_right(wp);
|
||||
else if (args_has(self->args, 'U'))
|
||||
} else if (args_has(self->args, 'U')) {
|
||||
server_unzoom_window(wp->window);
|
||||
wp = window_pane_find_up(wp);
|
||||
else if (args_has(self->args, 'D'))
|
||||
} else if (args_has(self->args, 'D')) {
|
||||
server_unzoom_window(wp->window);
|
||||
wp = window_pane_find_down(wp);
|
||||
}
|
||||
if (wp == NULL)
|
||||
return (CMD_RETURN_NORMAL);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -29,43 +29,62 @@
|
|||
enum cmd_retval cmd_select_window_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_select_window_entry = {
|
||||
"select-window", "selectw",
|
||||
"lnpTt:", 0, 0,
|
||||
"[-lnpT] " CMD_TARGET_WINDOW_USAGE,
|
||||
0,
|
||||
cmd_select_window_exec
|
||||
.name = "select-window",
|
||||
.alias = "selectw",
|
||||
|
||||
.args = { "lnpTt:", 0, 0 },
|
||||
.usage = "[-lnpT] " CMD_TARGET_WINDOW_USAGE,
|
||||
|
||||
.tflag = CMD_WINDOW,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_select_window_exec
|
||||
};
|
||||
|
||||
const struct cmd_entry cmd_next_window_entry = {
|
||||
"next-window", "next",
|
||||
"at:", 0, 0,
|
||||
"[-a] " CMD_TARGET_SESSION_USAGE,
|
||||
0,
|
||||
cmd_select_window_exec
|
||||
.name = "next-window",
|
||||
.alias = "next",
|
||||
|
||||
.args = { "at:", 0, 0 },
|
||||
.usage = "[-a] " CMD_TARGET_SESSION_USAGE,
|
||||
|
||||
.tflag = CMD_SESSION,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_select_window_exec
|
||||
};
|
||||
|
||||
const struct cmd_entry cmd_previous_window_entry = {
|
||||
"previous-window", "prev",
|
||||
"at:", 0, 0,
|
||||
"[-a] " CMD_TARGET_SESSION_USAGE,
|
||||
0,
|
||||
cmd_select_window_exec
|
||||
.name = "previous-window",
|
||||
.alias = "prev",
|
||||
|
||||
.args = { "at:", 0, 0 },
|
||||
.usage = "[-a] " CMD_TARGET_SESSION_USAGE,
|
||||
|
||||
.tflag = CMD_SESSION,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_select_window_exec
|
||||
};
|
||||
|
||||
const struct cmd_entry cmd_last_window_entry = {
|
||||
"last-window", "last",
|
||||
"t:", 0, 0,
|
||||
CMD_TARGET_SESSION_USAGE,
|
||||
0,
|
||||
cmd_select_window_exec
|
||||
.name = "last-window",
|
||||
.alias = "last",
|
||||
|
||||
.args = { "t:", 0, 0 },
|
||||
.usage = CMD_TARGET_SESSION_USAGE,
|
||||
|
||||
.tflag = CMD_SESSION,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_select_window_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_select_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct winlink *wl;
|
||||
struct session *s;
|
||||
struct winlink *wl = cmdq->state.tflag.wl;
|
||||
struct session *s = cmdq->state.tflag.s;
|
||||
int next, previous, last, activity;
|
||||
|
||||
next = self->entry == &cmd_next_window_entry;
|
||||
|
|
@ -79,10 +98,6 @@ cmd_select_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
last = 1;
|
||||
|
||||
if (next || previous || last) {
|
||||
s = cmd_find_session(cmdq, args_get(args, 't'), 0);
|
||||
if (s == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
||||
activity = args_has(self->args, 'a');
|
||||
if (next) {
|
||||
if (session_next(s, activity) != 0) {
|
||||
|
|
@ -103,10 +118,6 @@ cmd_select_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
|
||||
server_redraw_session(s);
|
||||
} else {
|
||||
wl = cmd_find_window(cmdq, args_get(args, 't'), &s);
|
||||
if (wl == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
||||
/*
|
||||
* If -T and select-window is invoked on same window as
|
||||
* current, switch to previous window.
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -30,30 +30,41 @@
|
|||
enum cmd_retval cmd_send_keys_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_send_keys_entry = {
|
||||
"send-keys", "send",
|
||||
"lRMt:", 0, -1,
|
||||
"[-lRM] " CMD_TARGET_PANE_USAGE " key ...",
|
||||
0,
|
||||
cmd_send_keys_exec
|
||||
.name = "send-keys",
|
||||
.alias = "send",
|
||||
|
||||
.args = { "lRMt:", 0, -1 },
|
||||
.usage = "[-lRM] " CMD_TARGET_PANE_USAGE " key ...",
|
||||
|
||||
.tflag = CMD_PANE,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_send_keys_exec
|
||||
};
|
||||
|
||||
const struct cmd_entry cmd_send_prefix_entry = {
|
||||
"send-prefix", NULL,
|
||||
"2t:", 0, 0,
|
||||
"[-2] " CMD_TARGET_PANE_USAGE,
|
||||
0,
|
||||
cmd_send_keys_exec
|
||||
.name = "send-prefix",
|
||||
.alias = NULL,
|
||||
|
||||
.args = { "2t:", 0, 0 },
|
||||
.usage = "[-2] " CMD_TARGET_PANE_USAGE,
|
||||
|
||||
.tflag = CMD_PANE,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_send_keys_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_send_keys_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct window_pane *wp = cmdq->state.tflag.wp;
|
||||
struct session *s = cmdq->state.tflag.s;
|
||||
struct mouse_event *m = &cmdq->item->mouse;
|
||||
struct window_pane *wp;
|
||||
struct session *s;
|
||||
const u_char *str;
|
||||
int i, key;
|
||||
const u_char *keystr;
|
||||
int i, literal;
|
||||
key_code key;
|
||||
|
||||
if (args_has(args, 'M')) {
|
||||
wp = cmd_mouse_pane(m, &s, NULL);
|
||||
|
|
@ -65,30 +76,30 @@ cmd_send_keys_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
if (cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
||||
if (self->entry == &cmd_send_prefix_entry) {
|
||||
if (args_has(args, '2'))
|
||||
key = options_get_number(&s->options, "prefix2");
|
||||
key = options_get_number(s->options, "prefix2");
|
||||
else
|
||||
key = options_get_number(&s->options, "prefix");
|
||||
key = options_get_number(s->options, "prefix");
|
||||
window_pane_key(wp, NULL, s, key, NULL);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
if (args_has(args, 'R'))
|
||||
input_reset(wp);
|
||||
input_reset(wp, 1);
|
||||
|
||||
for (i = 0; i < args->argc; i++) {
|
||||
str = args->argv[i];
|
||||
|
||||
if (!args_has(args, 'l') &&
|
||||
(key = key_string_lookup_string(str)) != KEYC_NONE) {
|
||||
window_pane_key(wp, NULL, s, key, NULL);
|
||||
} else {
|
||||
for (; *str != '\0'; str++)
|
||||
window_pane_key(wp, NULL, s, *str, NULL);
|
||||
literal = args_has(args, 'l');
|
||||
if (!literal) {
|
||||
key = key_string_lookup_string(args->argv[i]);
|
||||
if (key != KEYC_NONE && key != KEYC_UNKNOWN)
|
||||
window_pane_key(wp, NULL, s, key, NULL);
|
||||
else
|
||||
literal = 1;
|
||||
}
|
||||
if (literal) {
|
||||
for (keystr = args->argv[i]; *keystr != '\0'; keystr++)
|
||||
window_pane_key(wp, NULL, s, *keystr, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -30,19 +30,25 @@
|
|||
enum cmd_retval cmd_set_buffer_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_set_buffer_entry = {
|
||||
"set-buffer", "setb",
|
||||
"ab:n:", 0, 1,
|
||||
"[-a] " CMD_BUFFER_USAGE " [-n new-buffer-name] data",
|
||||
0,
|
||||
cmd_set_buffer_exec
|
||||
.name = "set-buffer",
|
||||
.alias = "setb",
|
||||
|
||||
.args = { "ab:n:", 0, 1 },
|
||||
.usage = "[-a] " CMD_BUFFER_USAGE " [-n new-buffer-name] data",
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_set_buffer_exec
|
||||
};
|
||||
|
||||
const struct cmd_entry cmd_delete_buffer_entry = {
|
||||
"delete-buffer", "deleteb",
|
||||
"b:", 0, 0,
|
||||
CMD_BUFFER_USAGE,
|
||||
0,
|
||||
cmd_set_buffer_exec
|
||||
.name = "delete-buffer",
|
||||
.alias = "deleteb",
|
||||
|
||||
.args = { "b:", 0, 0 },
|
||||
.usage = CMD_BUFFER_USAGE,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_set_buffer_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -30,20 +30,24 @@
|
|||
enum cmd_retval cmd_set_environment_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_set_environment_entry = {
|
||||
"set-environment", "setenv",
|
||||
"grt:u", 1, 2,
|
||||
"[-gru] " CMD_TARGET_SESSION_USAGE " name [value]",
|
||||
0,
|
||||
cmd_set_environment_exec
|
||||
.name = "set-environment",
|
||||
.alias = "setenv",
|
||||
|
||||
.args = { "grt:u", 1, 2 },
|
||||
.usage = "[-gru] " CMD_TARGET_SESSION_USAGE " name [value]",
|
||||
|
||||
.tflag = CMD_SESSION_CANFAIL,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_set_environment_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_set_environment_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct session *s;
|
||||
struct environ *env;
|
||||
const char *name, *value;
|
||||
const char *name, *value, *target;
|
||||
|
||||
name = args->argv[0];
|
||||
if (*name == '\0') {
|
||||
|
|
@ -61,11 +65,17 @@ cmd_set_environment_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
value = args->argv[1];
|
||||
|
||||
if (args_has(self->args, 'g'))
|
||||
env = &global_environ;
|
||||
env = global_environ;
|
||||
else {
|
||||
if ((s = cmd_find_session(cmdq, args_get(args, 't'), 0)) == NULL)
|
||||
if (cmdq->state.tflag.s == NULL) {
|
||||
target = args_get(args, 't');
|
||||
if (target != NULL)
|
||||
cmdq_error(cmdq, "no such session: %s", target);
|
||||
else
|
||||
cmdq_error(cmdq, "no current session");
|
||||
return (CMD_RETURN_ERROR);
|
||||
env = &s->environ;
|
||||
}
|
||||
env = cmdq->state.tflag.s->environ;
|
||||
}
|
||||
|
||||
if (args_has(self->args, 'u')) {
|
||||
|
|
@ -79,13 +89,13 @@ cmd_set_environment_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
cmdq_error(cmdq, "can't specify a value with -r");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
environ_set(env, name, NULL);
|
||||
environ_clear(env, name);
|
||||
} else {
|
||||
if (value == NULL) {
|
||||
cmdq_error(cmdq, "no value specified");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
environ_set(env, name, value);
|
||||
environ_set(env, name, "%s", value);
|
||||
}
|
||||
|
||||
return (CMD_RETURN_NORMAL);
|
||||
|
|
|
|||
120
cmd-set-hook.c
Normal file
120
cmd-set-hook.c
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012 Thomas Adam <thomas@xteddy.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "tmux.h"
|
||||
|
||||
/*
|
||||
* Set or show global or session hooks.
|
||||
*/
|
||||
|
||||
enum cmd_retval cmd_set_hook_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_set_hook_entry = {
|
||||
.name = "set-hook",
|
||||
.alias = NULL,
|
||||
|
||||
.args = { "gt:u", 1, 2 },
|
||||
.usage = "[-gu] " CMD_TARGET_SESSION_USAGE " hook-name [command]",
|
||||
|
||||
.tflag = CMD_SESSION,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_set_hook_exec
|
||||
};
|
||||
|
||||
const struct cmd_entry cmd_show_hooks_entry = {
|
||||
.name = "show-hooks",
|
||||
.alias = NULL,
|
||||
|
||||
.args = { "gt:", 0, 1 },
|
||||
.usage = "[-g] " CMD_TARGET_SESSION_USAGE,
|
||||
|
||||
.tflag = CMD_SESSION,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_set_hook_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_set_hook_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct cmd_list *cmdlist;
|
||||
struct hooks *hooks;
|
||||
struct hook *hook;
|
||||
char *cause, *tmp;
|
||||
const char *name, *cmd;
|
||||
|
||||
if (args_has(args, 'g'))
|
||||
hooks = global_hooks;
|
||||
else
|
||||
hooks = cmdq->state.tflag.s->hooks;
|
||||
|
||||
if (self->entry == &cmd_show_hooks_entry) {
|
||||
hook = hooks_first(hooks);
|
||||
while (hook != NULL) {
|
||||
tmp = cmd_list_print(hook->cmdlist);
|
||||
cmdq_print(cmdq, "%s -> %s", hook->name, tmp);
|
||||
free(tmp);
|
||||
|
||||
hook = hooks_next(hook);
|
||||
}
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
name = args->argv[0];
|
||||
if (*name == '\0') {
|
||||
cmdq_error(cmdq, "invalid hook name");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
if (args->argc < 2)
|
||||
cmd = NULL;
|
||||
else
|
||||
cmd = args->argv[1];
|
||||
|
||||
if (args_has(args, 'u')) {
|
||||
if (cmd != NULL) {
|
||||
cmdq_error(cmdq, "command passed to unset hook: %s",
|
||||
name);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
hooks_remove(hooks, name);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
if (cmd == NULL) {
|
||||
cmdq_error(cmdq, "no command to set hook: %s", name);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
if (cmd_string_parse(cmd, &cmdlist, NULL, 0, &cause) != 0) {
|
||||
if (cause != NULL) {
|
||||
cmdq_error(cmdq, "%s", cause);
|
||||
free(cause);
|
||||
}
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
hooks_add(hooks, name, cmdlist);
|
||||
cmd_list_free(cmdlist);
|
||||
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
157
cmd-set-option.c
157
cmd-set-option.c
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -65,32 +65,42 @@ struct options_entry *cmd_set_option_style(struct cmd *, struct cmd_q *,
|
|||
const char *);
|
||||
|
||||
const struct cmd_entry cmd_set_option_entry = {
|
||||
"set-option", "set",
|
||||
"agoqst:uw", 1, 2,
|
||||
"[-agosquw] [-t target-session|target-window] option [value]",
|
||||
0,
|
||||
cmd_set_option_exec
|
||||
.name = "set-option",
|
||||
.alias = "set",
|
||||
|
||||
.args = { "agoqst:uw", 1, 2 },
|
||||
.usage = "[-agosquw] [-t target-window] option [value]",
|
||||
|
||||
.tflag = CMD_WINDOW_CANFAIL,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_set_option_exec
|
||||
};
|
||||
|
||||
const struct cmd_entry cmd_set_window_option_entry = {
|
||||
"set-window-option", "setw",
|
||||
"agoqt:u", 1, 2,
|
||||
"[-agoqu] " CMD_TARGET_WINDOW_USAGE " option [value]",
|
||||
0,
|
||||
cmd_set_option_exec
|
||||
.name = "set-window-option",
|
||||
.alias = "setw",
|
||||
|
||||
.args = { "agoqt:u", 1, 2 },
|
||||
.usage = "[-agoqu] " CMD_TARGET_WINDOW_USAGE " option [value]",
|
||||
|
||||
.tflag = CMD_WINDOW_CANFAIL,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_set_option_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
const struct options_table_entry *table, *oe;
|
||||
struct session *s;
|
||||
struct winlink *wl;
|
||||
struct client *c;
|
||||
struct options *oo;
|
||||
struct session *s = cmdq->state.tflag.s;
|
||||
struct winlink *wl = cmdq->state.tflag.wl;
|
||||
struct window *w;
|
||||
const char *optstr, *valstr;
|
||||
struct client *c;
|
||||
const struct options_table_entry *oe;
|
||||
struct options *oo;
|
||||
const char *optstr, *valstr, *target;
|
||||
|
||||
/* Get the option name and value. */
|
||||
optstr = args->argv[0];
|
||||
|
|
@ -108,8 +118,8 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
return (cmd_set_option_user(self, cmdq, optstr, valstr));
|
||||
|
||||
/* Find the option entry, try each table. */
|
||||
table = oe = NULL;
|
||||
if (options_table_find(optstr, &table, &oe) != 0) {
|
||||
oe = NULL;
|
||||
if (options_table_find(optstr, &oe) != 0) {
|
||||
if (!args_has(args, 'q')) {
|
||||
cmdq_error(cmdq, "ambiguous option: %s", optstr);
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
|
@ -124,37 +134,35 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
/* Work out the tree from the table. */
|
||||
if (table == server_options_table)
|
||||
oo = &global_options;
|
||||
else if (table == window_options_table) {
|
||||
/* Work out the tree from the scope of the option. */
|
||||
if (oe->scope == OPTIONS_TABLE_SERVER)
|
||||
oo = global_options;
|
||||
else if (oe->scope == OPTIONS_TABLE_WINDOW) {
|
||||
if (args_has(self->args, 'g'))
|
||||
oo = &global_w_options;
|
||||
else {
|
||||
wl = cmd_find_window(cmdq, args_get(args, 't'), NULL);
|
||||
if (wl == NULL) {
|
||||
cmdq_error(cmdq,
|
||||
"couldn't set '%s'%s", optstr,
|
||||
(!args_has(args, 't') && !args_has(args,
|
||||
'g')) ? " need target window or -g" : "");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
oo = &wl->window->options;
|
||||
}
|
||||
} else if (table == session_options_table) {
|
||||
oo = global_w_options;
|
||||
else if (wl == NULL) {
|
||||
target = args_get(args, 't');
|
||||
if (target != NULL) {
|
||||
cmdq_error(cmdq, "no such window: %s",
|
||||
target);
|
||||
} else
|
||||
cmdq_error(cmdq, "no current window");
|
||||
return (CMD_RETURN_ERROR);
|
||||
} else
|
||||
oo = wl->window->options;
|
||||
} else if (oe->scope == OPTIONS_TABLE_SESSION) {
|
||||
if (args_has(self->args, 'g'))
|
||||
oo = &global_s_options;
|
||||
else {
|
||||
s = cmd_find_session(cmdq, args_get(args, 't'), 0);
|
||||
if (s == NULL) {
|
||||
cmdq_error(cmdq,
|
||||
"couldn't set '%s'%s", optstr,
|
||||
(!args_has(args, 't') && !args_has(args,
|
||||
'g')) ? " need target session or -g" : "");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
oo = &s->options;
|
||||
}
|
||||
oo = global_s_options;
|
||||
else if (s == NULL) {
|
||||
target = args_get(args, 't');
|
||||
if (target != NULL) {
|
||||
cmdq_error(cmdq, "no such session: %s",
|
||||
target);
|
||||
} else
|
||||
cmdq_error(cmdq, "no current session");
|
||||
return (CMD_RETURN_ERROR);
|
||||
} else
|
||||
oo = s->options;
|
||||
} else {
|
||||
cmdq_error(cmdq, "unknown table");
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
|
@ -179,10 +187,14 @@ cmd_set_option_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
/* Start or stop timers if necessary. */
|
||||
if (strcmp(oe->name, "automatic-rename") == 0) {
|
||||
RB_FOREACH(w, windows, &windows) {
|
||||
if (options_get_number(&w->options, "automatic-rename"))
|
||||
if (options_get_number(w->options, "automatic-rename"))
|
||||
w->active->flags |= PANE_CHANGED;
|
||||
}
|
||||
}
|
||||
if (strcmp(oe->name, "key-table") == 0) {
|
||||
TAILQ_FOREACH(c, &clients, entry)
|
||||
server_client_set_key_table(c, NULL);
|
||||
}
|
||||
if (strcmp(oe->name, "status") == 0 ||
|
||||
strcmp(oe->name, "status-interval") == 0)
|
||||
status_timer_start_all();
|
||||
|
|
@ -205,31 +217,23 @@ cmd_set_option_user(struct cmd *self, struct cmd_q *cmdq, const char *optstr,
|
|||
const char *valstr)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct session *s;
|
||||
struct winlink *wl;
|
||||
struct session *s = cmdq->state.tflag.s;
|
||||
struct winlink *wl = cmdq->state.tflag.wl;
|
||||
struct options *oo;
|
||||
|
||||
if (args_has(args, 's'))
|
||||
oo = &global_options;
|
||||
oo = global_options;
|
||||
else if (args_has(self->args, 'w') ||
|
||||
self->entry == &cmd_set_window_option_entry) {
|
||||
if (args_has(self->args, 'g'))
|
||||
oo = &global_w_options;
|
||||
else {
|
||||
wl = cmd_find_window(cmdq, args_get(args, 't'), NULL);
|
||||
if (wl == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
oo = &wl->window->options;
|
||||
}
|
||||
oo = global_w_options;
|
||||
else
|
||||
oo = wl->window->options;
|
||||
} else {
|
||||
if (args_has(self->args, 'g'))
|
||||
oo = &global_s_options;
|
||||
else {
|
||||
s = cmd_find_session(cmdq, args_get(args, 't'), 0);
|
||||
if (s == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
oo = &s->options;
|
||||
}
|
||||
oo = global_s_options;
|
||||
else
|
||||
oo = s->options;
|
||||
}
|
||||
|
||||
if (args_has(args, 'u')) {
|
||||
|
|
@ -276,7 +280,7 @@ cmd_set_option_unset(struct cmd *self, struct cmd_q *cmdq,
|
|||
return (-1);
|
||||
}
|
||||
|
||||
if (args_has(args, 'g') || oo == &global_options) {
|
||||
if (args_has(args, 'g') || oo == global_options) {
|
||||
switch (oe->type) {
|
||||
case OPTIONS_TABLE_STRING:
|
||||
options_set_string(oo, oe->name, "%s", oe->default_str);
|
||||
|
|
@ -350,7 +354,7 @@ cmd_set_option_set(struct cmd *self, struct cmd_q *cmdq,
|
|||
|
||||
/* Set a string option. */
|
||||
struct options_entry *
|
||||
cmd_set_option_string(struct cmd *self, unused struct cmd_q *cmdq,
|
||||
cmd_set_option_string(struct cmd *self, __unused struct cmd_q *cmdq,
|
||||
const struct options_table_entry *oe, struct options *oo,
|
||||
const char *value)
|
||||
{
|
||||
|
|
@ -372,7 +376,7 @@ cmd_set_option_string(struct cmd *self, unused struct cmd_q *cmdq,
|
|||
|
||||
/* Set a number option. */
|
||||
struct options_entry *
|
||||
cmd_set_option_number(unused struct cmd *self, struct cmd_q *cmdq,
|
||||
cmd_set_option_number(__unused struct cmd *self, struct cmd_q *cmdq,
|
||||
const struct options_table_entry *oe, struct options *oo,
|
||||
const char *value)
|
||||
{
|
||||
|
|
@ -390,13 +394,14 @@ cmd_set_option_number(unused struct cmd *self, struct cmd_q *cmdq,
|
|||
|
||||
/* Set a key option. */
|
||||
struct options_entry *
|
||||
cmd_set_option_key(unused struct cmd *self, struct cmd_q *cmdq,
|
||||
cmd_set_option_key(__unused struct cmd *self, struct cmd_q *cmdq,
|
||||
const struct options_table_entry *oe, struct options *oo,
|
||||
const char *value)
|
||||
{
|
||||
int key;
|
||||
key_code key;
|
||||
|
||||
if ((key = key_string_lookup_string(value)) == KEYC_NONE) {
|
||||
key = key_string_lookup_string(value);
|
||||
if (key == KEYC_UNKNOWN) {
|
||||
cmdq_error(cmdq, "bad key: %s", value);
|
||||
return (NULL);
|
||||
}
|
||||
|
|
@ -406,7 +411,7 @@ cmd_set_option_key(unused struct cmd *self, struct cmd_q *cmdq,
|
|||
|
||||
/* Set a colour option. */
|
||||
struct options_entry *
|
||||
cmd_set_option_colour(unused struct cmd *self, struct cmd_q *cmdq,
|
||||
cmd_set_option_colour(__unused struct cmd *self, struct cmd_q *cmdq,
|
||||
const struct options_table_entry *oe, struct options *oo,
|
||||
const char *value)
|
||||
{
|
||||
|
|
@ -422,7 +427,7 @@ cmd_set_option_colour(unused struct cmd *self, struct cmd_q *cmdq,
|
|||
|
||||
/* Set an attributes option. */
|
||||
struct options_entry *
|
||||
cmd_set_option_attributes(unused struct cmd *self, struct cmd_q *cmdq,
|
||||
cmd_set_option_attributes(__unused struct cmd *self, struct cmd_q *cmdq,
|
||||
const struct options_table_entry *oe, struct options *oo,
|
||||
const char *value)
|
||||
{
|
||||
|
|
@ -438,7 +443,7 @@ cmd_set_option_attributes(unused struct cmd *self, struct cmd_q *cmdq,
|
|||
|
||||
/* Set a flag option. */
|
||||
struct options_entry *
|
||||
cmd_set_option_flag(unused struct cmd *self, struct cmd_q *cmdq,
|
||||
cmd_set_option_flag(__unused struct cmd *self, struct cmd_q *cmdq,
|
||||
const struct options_table_entry *oe, struct options *oo,
|
||||
const char *value)
|
||||
{
|
||||
|
|
@ -466,7 +471,7 @@ cmd_set_option_flag(unused struct cmd *self, struct cmd_q *cmdq,
|
|||
|
||||
/* Set a choice option. */
|
||||
struct options_entry *
|
||||
cmd_set_option_choice(unused struct cmd *self, struct cmd_q *cmdq,
|
||||
cmd_set_option_choice(__unused struct cmd *self, struct cmd_q *cmdq,
|
||||
const struct options_table_entry *oe, struct options *oo,
|
||||
const char *value)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -34,11 +34,16 @@ void cmd_show_environment_print(struct cmd *, struct cmd_q *,
|
|||
struct environ_entry *);
|
||||
|
||||
const struct cmd_entry cmd_show_environment_entry = {
|
||||
"show-environment", "showenv",
|
||||
"gst:", 0, 1,
|
||||
"[-gs] " CMD_TARGET_SESSION_USAGE " [name]",
|
||||
0,
|
||||
cmd_show_environment_exec
|
||||
.name = "show-environment",
|
||||
.alias = "showenv",
|
||||
|
||||
.args = { "gst:", 0, 1 },
|
||||
.usage = "[-gs] " CMD_TARGET_SESSION_USAGE " [name]",
|
||||
|
||||
.tflag = CMD_SESSION_CANFAIL,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_show_environment_exec
|
||||
};
|
||||
|
||||
char *
|
||||
|
|
@ -86,17 +91,29 @@ enum cmd_retval
|
|||
cmd_show_environment_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct session *s;
|
||||
struct environ *env;
|
||||
struct environ_entry *envent;
|
||||
const char *target;
|
||||
|
||||
if ((target = args_get(args, 't')) != NULL) {
|
||||
if (cmdq->state.tflag.s == NULL) {
|
||||
cmdq_error(cmdq, "no such session: %s", target);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
if (args_has(self->args, 'g'))
|
||||
env = &global_environ;
|
||||
env = global_environ;
|
||||
else {
|
||||
s = cmd_find_session(cmdq, args_get(args, 't'), 0);
|
||||
if (s == NULL)
|
||||
if (cmdq->state.tflag.s == NULL) {
|
||||
target = args_get(args, 't');
|
||||
if (target != NULL)
|
||||
cmdq_error(cmdq, "no such session: %s", target);
|
||||
else
|
||||
cmdq_error(cmdq, "no current session");
|
||||
return (CMD_RETURN_ERROR);
|
||||
env = &s->environ;
|
||||
}
|
||||
env = cmdq->state.tflag.s->environ;
|
||||
}
|
||||
|
||||
if (args->argc != 0) {
|
||||
|
|
@ -109,7 +126,10 @@ cmd_show_environment_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
RB_FOREACH(envent, environ, env)
|
||||
envent = environ_first(env);
|
||||
while (envent != NULL) {
|
||||
cmd_show_environment_print(self, cmdq, envent);
|
||||
envent = environ_next(envent);
|
||||
}
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -31,41 +31,32 @@
|
|||
enum cmd_retval cmd_show_messages_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_show_messages_entry = {
|
||||
"show-messages", "showmsgs",
|
||||
"IJTt:", 0, 0,
|
||||
"[-IJT] " CMD_TARGET_CLIENT_USAGE,
|
||||
0,
|
||||
cmd_show_messages_exec
|
||||
.name = "show-messages",
|
||||
.alias = "showmsgs",
|
||||
|
||||
.args = { "JTt:", 0, 0 },
|
||||
.usage = "[-JT] " CMD_TARGET_CLIENT_USAGE,
|
||||
|
||||
.tflag = CMD_CLIENT,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_show_messages_exec
|
||||
};
|
||||
|
||||
const struct cmd_entry cmd_server_info_entry = {
|
||||
"server-info", "info",
|
||||
"", 0, 0,
|
||||
"",
|
||||
0,
|
||||
cmd_show_messages_exec
|
||||
.name = "server-info",
|
||||
.alias = "info",
|
||||
|
||||
.args = { "", 0, 0 },
|
||||
.usage = "",
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_show_messages_exec
|
||||
};
|
||||
|
||||
int cmd_show_messages_server(struct cmd_q *);
|
||||
int cmd_show_messages_terminals(struct cmd_q *, int);
|
||||
int cmd_show_messages_jobs(struct cmd_q *, int);
|
||||
|
||||
int
|
||||
cmd_show_messages_server(struct cmd_q *cmdq)
|
||||
{
|
||||
char *tim;
|
||||
|
||||
tim = ctime(&start_time);
|
||||
*strchr(tim, '\n') = '\0';
|
||||
|
||||
cmdq_print(cmdq, "started %s", tim);
|
||||
cmdq_print(cmdq, "socket path %s", socket_path);
|
||||
cmdq_print(cmdq, "debug level %d", debug_level);
|
||||
cmdq_print(cmdq, "protocol version %d", PROTOCOL_VERSION);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
cmd_show_messages_terminals(struct cmd_q *cmdq, int blank)
|
||||
{
|
||||
|
|
@ -110,16 +101,12 @@ enum cmd_retval
|
|||
cmd_show_messages_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct client *c;
|
||||
struct client *c = cmdq->state.c;
|
||||
struct message_entry *msg;
|
||||
char *tim;
|
||||
int done, blank;
|
||||
|
||||
done = blank = 0;
|
||||
if (args_has(args, 'I') || self->entry == &cmd_server_info_entry) {
|
||||
blank = cmd_show_messages_server(cmdq);
|
||||
done = 1;
|
||||
}
|
||||
if (args_has(args, 'T') || self->entry == &cmd_server_info_entry) {
|
||||
blank = cmd_show_messages_terminals(cmdq, blank);
|
||||
done = 1;
|
||||
|
|
@ -131,9 +118,6 @@ cmd_show_messages_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
if (done)
|
||||
return (CMD_RETURN_NORMAL);
|
||||
|
||||
if ((c = cmd_find_client(cmdq, args_get(args, 't'), 0)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
||||
TAILQ_FOREACH(msg, &c->message_log, entry) {
|
||||
tim = ctime(&msg->msg_time);
|
||||
*strchr(tim, '\n') = '\0';
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -32,63 +32,80 @@ enum cmd_retval cmd_show_options_exec(struct cmd *, struct cmd_q *);
|
|||
enum cmd_retval cmd_show_options_one(struct cmd *, struct cmd_q *,
|
||||
struct options *, int);
|
||||
enum cmd_retval cmd_show_options_all(struct cmd *, struct cmd_q *,
|
||||
const struct options_table_entry *, struct options *);
|
||||
struct options *, enum options_table_scope);
|
||||
|
||||
const struct cmd_entry cmd_show_options_entry = {
|
||||
"show-options", "show",
|
||||
"gqst:vw", 0, 1,
|
||||
"[-gqsvw] [-t target-session|target-window] [option]",
|
||||
0,
|
||||
cmd_show_options_exec
|
||||
.name = "show-options",
|
||||
.alias = "show",
|
||||
|
||||
.args = { "gqst:vw", 0, 1 },
|
||||
.usage = "[-gqsvw] [-t target-session|target-window] [option]",
|
||||
|
||||
.tflag = CMD_WINDOW_CANFAIL,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_show_options_exec
|
||||
};
|
||||
|
||||
const struct cmd_entry cmd_show_window_options_entry = {
|
||||
"show-window-options", "showw",
|
||||
"gvt:", 0, 1,
|
||||
"[-gv] " CMD_TARGET_WINDOW_USAGE " [option]",
|
||||
0,
|
||||
cmd_show_options_exec
|
||||
.name = "show-window-options",
|
||||
.alias = "showw",
|
||||
|
||||
.args = { "gvt:", 0, 1 },
|
||||
.usage = "[-gv] " CMD_TARGET_WINDOW_USAGE " [option]",
|
||||
|
||||
.tflag = CMD_WINDOW_CANFAIL,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_show_options_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_show_options_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct session *s;
|
||||
struct winlink *wl;
|
||||
const struct options_table_entry *table;
|
||||
struct options *oo;
|
||||
int quiet;
|
||||
struct args *args = self->args;
|
||||
struct session *s = cmdq->state.tflag.s;
|
||||
struct winlink *wl = cmdq->state.tflag.wl;
|
||||
struct options *oo;
|
||||
enum options_table_scope scope;
|
||||
int quiet;
|
||||
const char *target;
|
||||
|
||||
if (args_has(self->args, 's')) {
|
||||
oo = &global_options;
|
||||
table = server_options_table;
|
||||
oo = global_options;
|
||||
scope = OPTIONS_TABLE_SERVER;
|
||||
} else if (args_has(self->args, 'w') ||
|
||||
self->entry == &cmd_show_window_options_entry) {
|
||||
table = window_options_table;
|
||||
scope = OPTIONS_TABLE_WINDOW;
|
||||
if (args_has(self->args, 'g'))
|
||||
oo = &global_w_options;
|
||||
else {
|
||||
wl = cmd_find_window(cmdq, args_get(args, 't'), NULL);
|
||||
if (wl == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
oo = &wl->window->options;
|
||||
}
|
||||
oo = global_w_options;
|
||||
else if (wl == NULL) {
|
||||
target = args_get(args, 't');
|
||||
if (target != NULL) {
|
||||
cmdq_error(cmdq, "no such window: %s", target);
|
||||
} else
|
||||
cmdq_error(cmdq, "no current window");
|
||||
return (CMD_RETURN_ERROR);
|
||||
} else
|
||||
oo = wl->window->options;
|
||||
} else {
|
||||
table = session_options_table;
|
||||
scope = OPTIONS_TABLE_SESSION;
|
||||
if (args_has(self->args, 'g'))
|
||||
oo = &global_s_options;
|
||||
else {
|
||||
s = cmd_find_session(cmdq, args_get(args, 't'), 0);
|
||||
if (s == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
oo = &s->options;
|
||||
}
|
||||
oo = global_s_options;
|
||||
else if (s == NULL) {
|
||||
target = args_get(args, 't');
|
||||
if (target != NULL) {
|
||||
cmdq_error(cmdq, "no such session: %s", target);
|
||||
} else
|
||||
cmdq_error(cmdq, "no current session");
|
||||
return (CMD_RETURN_ERROR);
|
||||
} else
|
||||
oo = s->options;
|
||||
}
|
||||
|
||||
quiet = args_has(self->args, 'q');
|
||||
if (args->argc == 0)
|
||||
return (cmd_show_options_all(self, cmdq, table, oo));
|
||||
return (cmd_show_options_all(self, cmdq, oo, scope));
|
||||
else
|
||||
return (cmd_show_options_one(self, cmdq, oo, quiet));
|
||||
}
|
||||
|
|
@ -99,7 +116,7 @@ cmd_show_options_one(struct cmd *self, struct cmd_q *cmdq,
|
|||
{
|
||||
struct args *args = self->args;
|
||||
const char *name = args->argv[0];
|
||||
const struct options_table_entry *table, *oe;
|
||||
const struct options_table_entry *oe;
|
||||
struct options_entry *o;
|
||||
const char *optval;
|
||||
|
||||
|
|
@ -118,14 +135,14 @@ retry:
|
|||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
table = oe = NULL;
|
||||
if (options_table_find(name, &table, &oe) != 0) {
|
||||
oe = NULL;
|
||||
if (options_table_find(name, &oe) != 0) {
|
||||
cmdq_error(cmdq, "ambiguous option: %s", name);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
if (oe == NULL) {
|
||||
if (quiet)
|
||||
return (CMD_RETURN_NORMAL);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
cmdq_error(cmdq, "unknown option: %s", name);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
|
@ -144,30 +161,33 @@ retry:
|
|||
}
|
||||
|
||||
enum cmd_retval
|
||||
cmd_show_options_all(struct cmd *self, struct cmd_q *cmdq,
|
||||
const struct options_table_entry *table, struct options *oo)
|
||||
cmd_show_options_all(struct cmd *self, struct cmd_q *cmdq, struct options *oo,
|
||||
enum options_table_scope scope)
|
||||
{
|
||||
const struct options_table_entry *oe;
|
||||
struct options_entry *o;
|
||||
const char *optval;
|
||||
int vflag;
|
||||
|
||||
RB_FOREACH(o, options_tree, &oo->tree) {
|
||||
o = options_first(oo);
|
||||
while (o != NULL) {
|
||||
if (*o->name == '@') {
|
||||
if (args_has(self->args, 'v'))
|
||||
cmdq_print(cmdq, "%s", o->str);
|
||||
else
|
||||
cmdq_print(cmdq, "%s \"%s\"", o->name, o->str);
|
||||
}
|
||||
o = options_next(o);
|
||||
}
|
||||
|
||||
for (oe = table; oe->name != NULL; oe++) {
|
||||
if (oe->style != NULL)
|
||||
vflag = args_has(self->args, 'v');
|
||||
for (oe = options_table; oe->name != NULL; oe++) {
|
||||
if (oe->style != NULL || oe->scope != scope)
|
||||
continue;
|
||||
if ((o = options_find1(oo, oe->name)) == NULL)
|
||||
continue;
|
||||
optval = options_table_print_entry(oe, o,
|
||||
args_has(self->args, 'v'));
|
||||
if (args_has(self->args, 'v'))
|
||||
optval = options_table_print_entry(oe, o, vflag);
|
||||
if (vflag)
|
||||
cmdq_print(cmdq, "%s", optval);
|
||||
else
|
||||
cmdq_print(cmdq, "%s %s", oe->name, optval);
|
||||
|
|
|
|||
|
|
@ -31,11 +31,14 @@ enum cmd_retval cmd_source_file_exec(struct cmd *, struct cmd_q *);
|
|||
void cmd_source_file_done(struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_source_file_entry = {
|
||||
"source-file", "source",
|
||||
"", 1, 1,
|
||||
"path",
|
||||
0,
|
||||
cmd_source_file_exec
|
||||
.name = "source-file",
|
||||
.alias = "source",
|
||||
|
||||
.args = { "", 1, 1 },
|
||||
.usage = "path",
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_source_file_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
|
|
@ -45,8 +48,7 @@ cmd_source_file_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
struct cmd_q *cmdq1;
|
||||
char *cause;
|
||||
|
||||
cmdq1 = cmdq_new(NULL);
|
||||
cmdq1->client = cmdq->client;
|
||||
cmdq1 = cmdq_new(cmdq->client);
|
||||
cmdq1->emptyfn = cmd_source_file_done;
|
||||
cmdq1->data = cmdq;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -35,44 +35,46 @@
|
|||
enum cmd_retval cmd_split_window_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_split_window_entry = {
|
||||
"split-window", "splitw",
|
||||
"bc:dF:l:hp:Pt:v", 0, -1,
|
||||
"[-bdhvP] [-c start-directory] [-F format] [-p percentage|-l size] "
|
||||
CMD_TARGET_PANE_USAGE " [command]",
|
||||
0,
|
||||
cmd_split_window_exec
|
||||
.name = "split-window",
|
||||
.alias = "splitw",
|
||||
|
||||
.args = { "bc:dF:l:hp:Pt:v", 0, -1 },
|
||||
.usage = "[-bdhvP] [-c start-directory] [-F format] "
|
||||
"[-p percentage|-l size] " CMD_TARGET_PANE_USAGE " [command]",
|
||||
|
||||
.tflag = CMD_PANE,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_split_window_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct session *s;
|
||||
struct winlink *wl;
|
||||
struct window *w;
|
||||
struct window_pane *wp, *new_wp = NULL;
|
||||
struct environ env;
|
||||
const char *cmd, *path, *shell, *template;
|
||||
struct session *s = cmdq->state.tflag.s;
|
||||
struct winlink *wl = cmdq->state.tflag.wl;
|
||||
struct window *w = wl->window;
|
||||
struct window_pane *wp = cmdq->state.tflag.wp, *new_wp = NULL;
|
||||
struct environ *env;
|
||||
const char *cmd, *path, *shell, *template, *cwd, *to_free;
|
||||
char **argv, *cause, *new_cause, *cp;
|
||||
u_int hlimit;
|
||||
int argc, size, percentage, cwd, fd = -1;
|
||||
int argc, size, percentage;
|
||||
enum layout_type type;
|
||||
struct layout_cell *lc;
|
||||
struct format_tree *ft;
|
||||
struct environ_entry *envent;
|
||||
|
||||
if ((wl = cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
w = wl->window;
|
||||
server_unzoom_window(w);
|
||||
|
||||
environ_init(&env);
|
||||
environ_copy(&global_environ, &env);
|
||||
environ_copy(&s->environ, &env);
|
||||
server_fill_environ(s, &env);
|
||||
env = environ_create();
|
||||
environ_copy(global_environ, env);
|
||||
environ_copy(s->environ, env);
|
||||
server_fill_environ(s, env);
|
||||
|
||||
if (args->argc == 0) {
|
||||
cmd = options_get_string(&s->options, "default-command");
|
||||
cmd = options_get_string(s->options, "default-command");
|
||||
if (cmd != NULL && *cmd != '\0') {
|
||||
argc = 1;
|
||||
argv = (char **)&cmd;
|
||||
|
|
@ -85,24 +87,12 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
argv = args->argv;
|
||||
}
|
||||
|
||||
to_free = NULL;
|
||||
if (args_has(args, 'c')) {
|
||||
ft = format_create();
|
||||
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, NULL,
|
||||
NULL);
|
||||
cp = format_expand(ft, args_get(args, 'c'));
|
||||
ft = format_create(cmdq, 0);
|
||||
format_defaults(ft, cmdq->state.c, s, NULL, NULL);
|
||||
to_free = cwd = format_expand(ft, args_get(args, 'c'));
|
||||
format_free(ft);
|
||||
|
||||
if (cp != NULL && *cp != '\0') {
|
||||
fd = open(cp, O_RDONLY|O_DIRECTORY);
|
||||
free(cp);
|
||||
if (fd == -1) {
|
||||
cmdq_error(cmdq, "bad working directory: %s",
|
||||
strerror(errno));
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
} else if (cp != NULL)
|
||||
free(cp);
|
||||
cwd = fd;
|
||||
} else if (cmdq->client != NULL && cmdq->client->session == NULL)
|
||||
cwd = cmdq->client->cwd;
|
||||
else
|
||||
|
|
@ -134,9 +124,9 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
else
|
||||
size = (wp->sx * percentage) / 100;
|
||||
}
|
||||
hlimit = options_get_number(&s->options, "history-limit");
|
||||
hlimit = options_get_number(s->options, "history-limit");
|
||||
|
||||
shell = options_get_string(&s->options, "default-shell");
|
||||
shell = options_get_string(s->options, "default-shell");
|
||||
if (*shell == '\0' || areshell(shell))
|
||||
shell = _PATH_BSHELL;
|
||||
|
||||
|
|
@ -150,13 +140,13 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
|
||||
path = NULL;
|
||||
if (cmdq->client != NULL && cmdq->client->session == NULL)
|
||||
envent = environ_find(&cmdq->client->environ, "PATH");
|
||||
envent = environ_find(cmdq->client->environ, "PATH");
|
||||
else
|
||||
envent = environ_find(&s->environ, "PATH");
|
||||
envent = environ_find(s->environ, "PATH");
|
||||
if (envent != NULL)
|
||||
path = envent->value;
|
||||
|
||||
if (window_pane_spawn(new_wp, argc, argv, path, shell, cwd, &env,
|
||||
if (window_pane_spawn(new_wp, argc, argv, path, shell, cwd, env,
|
||||
s->tio, &cause) != 0)
|
||||
goto error;
|
||||
|
||||
|
|
@ -169,15 +159,14 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
} else
|
||||
server_status_session(s);
|
||||
|
||||
environ_free(&env);
|
||||
environ_free(env);
|
||||
|
||||
if (args_has(args, 'P')) {
|
||||
if ((template = args_get(args, 'F')) == NULL)
|
||||
template = SPLIT_WINDOW_TEMPLATE;
|
||||
|
||||
ft = format_create();
|
||||
format_defaults(ft, cmd_find_client(cmdq, NULL, 1), s, wl,
|
||||
new_wp);
|
||||
ft = format_create(cmdq, 0);
|
||||
format_defaults(ft, cmdq->state.c, s, wl, new_wp);
|
||||
|
||||
cp = format_expand(ft, template);
|
||||
cmdq_print(cmdq, "%s", cp);
|
||||
|
|
@ -187,19 +176,20 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
}
|
||||
notify_window_layout_changed(w);
|
||||
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
if (to_free != NULL)
|
||||
free((void *)to_free);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
|
||||
error:
|
||||
environ_free(&env);
|
||||
environ_free(env);
|
||||
if (new_wp != NULL) {
|
||||
layout_close_pane(new_wp);
|
||||
window_remove_pane(w, new_wp);
|
||||
}
|
||||
cmdq_error(cmdq, "create pane failed: %s", cause);
|
||||
free(cause);
|
||||
if (fd != -1)
|
||||
close(fd);
|
||||
|
||||
if (to_free != NULL)
|
||||
free((void *)to_free);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
|
|
|||
12
cmd-string.c
12
cmd-string.c
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -126,7 +126,7 @@ cmd_string_parse(const char *s, struct cmd_list **cmdlist, const char *file,
|
|||
whitespace = argv[0] + strcspn(argv[0], " \t");
|
||||
if (equals == NULL || equals > whitespace)
|
||||
break;
|
||||
environ_put(&global_environ, argv[0]);
|
||||
environ_put(global_environ, argv[0]);
|
||||
argc--;
|
||||
memmove(argv, argv + 1, argc * (sizeof *argv));
|
||||
}
|
||||
|
|
@ -303,10 +303,14 @@ cmd_string_variable(const char *s, size_t *p)
|
|||
buf = xrealloc(buf, len + 1);
|
||||
buf[len] = '\0';
|
||||
|
||||
envent = environ_find(&global_environ, buf);
|
||||
envent = environ_find(global_environ, buf);
|
||||
free(buf);
|
||||
if (envent == NULL)
|
||||
return (xstrdup(""));
|
||||
#ifdef TMATE
|
||||
if (envent->value == NULL)
|
||||
return (xstrdup(""));
|
||||
#endif
|
||||
return (xstrdup(envent->value));
|
||||
|
||||
error:
|
||||
|
|
@ -326,7 +330,7 @@ cmd_string_expand_tilde(const char *s, size_t *p)
|
|||
|
||||
last = cmd_string_getc(s, p);
|
||||
if (last == EOF || last == '/' || last == ' '|| last == '\t') {
|
||||
envent = environ_find(&global_environ, "HOME");
|
||||
envent = environ_find(global_environ, "HOME");
|
||||
if (envent != NULL && *envent->value != '\0')
|
||||
home = envent->value;
|
||||
else if ((pw = getpwuid(getuid())) != NULL)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -29,55 +29,53 @@
|
|||
enum cmd_retval cmd_swap_pane_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_swap_pane_entry = {
|
||||
"swap-pane", "swapp",
|
||||
"dDs:t:U", 0, 0,
|
||||
"[-dDU] " CMD_SRCDST_PANE_USAGE,
|
||||
0,
|
||||
cmd_swap_pane_exec
|
||||
.name = "swap-pane",
|
||||
.alias = "swapp",
|
||||
|
||||
.args = { "dDs:t:U", 0, 0 },
|
||||
.usage = "[-dDU] " CMD_SRCDST_PANE_USAGE,
|
||||
|
||||
.sflag = CMD_PANE_MARKED,
|
||||
.tflag = CMD_PANE,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_swap_pane_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_swap_pane_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct winlink *src_wl, *dst_wl;
|
||||
struct window *src_w, *dst_w;
|
||||
struct window_pane *tmp_wp, *src_wp, *dst_wp;
|
||||
struct layout_cell *src_lc, *dst_lc;
|
||||
u_int sx, sy, xoff, yoff;
|
||||
|
||||
dst_wl = cmd_find_pane(cmdq, args_get(args, 't'), NULL, &dst_wp);
|
||||
if (dst_wl == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
dst_w = dst_wl->window;
|
||||
dst_w = cmdq->state.tflag.wl->window;
|
||||
dst_wp = cmdq->state.tflag.wp;
|
||||
src_w = cmdq->state.sflag.wl->window;
|
||||
src_wp = cmdq->state.sflag.wp;
|
||||
server_unzoom_window(dst_w);
|
||||
|
||||
if (!args_has(args, 's')) {
|
||||
if (args_has(self->args, 'D')) {
|
||||
src_w = dst_w;
|
||||
if (args_has(self->args, 'D')) {
|
||||
src_wp = TAILQ_NEXT(dst_wp, entry);
|
||||
if (src_wp == NULL)
|
||||
src_wp = TAILQ_FIRST(&dst_w->panes);
|
||||
} else if (args_has(self->args, 'U')) {
|
||||
src_wp = TAILQ_PREV(dst_wp, window_panes, entry);
|
||||
if (src_wp == NULL)
|
||||
src_wp = TAILQ_LAST(&dst_w->panes, window_panes);
|
||||
} else {
|
||||
src_wl = cmd_find_pane_marked(cmdq, NULL, NULL,
|
||||
&src_wp);
|
||||
if (src_wl == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
src_w = src_wl->window;
|
||||
}
|
||||
} else {
|
||||
src_wl = cmd_find_pane_marked(cmdq, args_get(args, 's'), NULL,
|
||||
&src_wp);
|
||||
if (src_wl == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
src_w = src_wl->window;
|
||||
src_wp = TAILQ_NEXT(dst_wp, entry);
|
||||
if (src_wp == NULL)
|
||||
src_wp = TAILQ_FIRST(&dst_w->panes);
|
||||
} else if (args_has(self->args, 'U')) {
|
||||
src_w = dst_w;
|
||||
src_wp = TAILQ_PREV(dst_wp, window_panes, entry);
|
||||
if (src_wp == NULL)
|
||||
src_wp = TAILQ_LAST(&dst_w->panes, window_panes);
|
||||
}
|
||||
server_unzoom_window(src_w);
|
||||
|
||||
#ifdef TMATE
|
||||
if (src_w != dst_w) {
|
||||
cmdq_error(cmdq, "swap pane on different window is not supported with tmate");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (src_wp == dst_wp)
|
||||
return (CMD_RETURN_NORMAL);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -29,34 +29,41 @@
|
|||
enum cmd_retval cmd_swap_window_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_swap_window_entry = {
|
||||
"swap-window", "swapw",
|
||||
"ds:t:", 0, 0,
|
||||
"[-d] " CMD_SRCDST_WINDOW_USAGE,
|
||||
0,
|
||||
cmd_swap_window_exec
|
||||
.name = "swap-window",
|
||||
.alias = "swapw",
|
||||
|
||||
.args = { "ds:t:", 0, 0 },
|
||||
.usage = "[-d] " CMD_SRCDST_WINDOW_USAGE,
|
||||
|
||||
.sflag = CMD_WINDOW_MARKED,
|
||||
.tflag = CMD_WINDOW,
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_swap_window_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_swap_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
const char *target_src, *target_dst;
|
||||
#ifdef TMATE
|
||||
cmdq_error(cmdq, "swap window is not supported with tmate");
|
||||
return (CMD_RETURN_ERROR);
|
||||
#else
|
||||
struct session *src, *dst;
|
||||
struct session_group *sg_src, *sg_dst;
|
||||
struct winlink *wl_src, *wl_dst;
|
||||
struct window *w;
|
||||
|
||||
target_src = args_get(args, 's');
|
||||
if ((wl_src = cmd_find_window_marked(cmdq, target_src, &src)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
target_dst = args_get(args, 't');
|
||||
if ((wl_dst = cmd_find_window(cmdq, target_dst, &dst)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
||||
wl_src = cmdq->state.sflag.wl;
|
||||
src = cmdq->state.sflag.s;
|
||||
sg_src = session_group_find(src);
|
||||
|
||||
wl_dst = cmdq->state.tflag.wl;
|
||||
dst = cmdq->state.tflag.s;
|
||||
sg_dst = session_group_find(dst);
|
||||
if (src != dst &&
|
||||
sg_src != NULL && sg_dst != NULL && sg_src == sg_dst) {
|
||||
|
||||
if (src != dst && sg_src != NULL && sg_dst != NULL &&
|
||||
sg_src == sg_dst) {
|
||||
cmdq_error(cmdq, "can't move window, sessions are grouped");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
|
@ -82,4 +89,5 @@ cmd_swap_window_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
recalculate_sizes();
|
||||
|
||||
return (CMD_RETURN_NORMAL);
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -30,34 +30,33 @@
|
|||
enum cmd_retval cmd_switch_client_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_switch_client_entry = {
|
||||
"switch-client", "switchc",
|
||||
"lc:Enpt:rT:", 0, 0,
|
||||
"[-Elnpr] [-c target-client] [-t target-session] [-T key-table]",
|
||||
CMD_READONLY,
|
||||
cmd_switch_client_exec
|
||||
.name = "switch-client",
|
||||
.alias = "switchc",
|
||||
|
||||
.args = { "lc:Enpt:rT:", 0, 0 },
|
||||
.usage = "[-Elnpr] [-c target-client] [-t target-session] "
|
||||
"[-T key-table]",
|
||||
|
||||
.cflag = CMD_CLIENT,
|
||||
.tflag = CMD_SESSION_WITHPANE,
|
||||
|
||||
.flags = CMD_READONLY,
|
||||
.exec = cmd_switch_client_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_switch_client_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
struct client *c;
|
||||
struct session *s = NULL;
|
||||
struct winlink *wl = NULL;
|
||||
struct window *w = NULL;
|
||||
struct window_pane *wp = NULL;
|
||||
const char *tflag, *tablename, *update;
|
||||
struct cmd_state *state = &cmdq->state;
|
||||
struct client *c = state->c;
|
||||
struct session *s = cmdq->state.tflag.s;
|
||||
struct window_pane *wp;
|
||||
const char *tablename, *update;
|
||||
struct key_table *table;
|
||||
|
||||
if ((c = cmd_find_client(cmdq, args_get(args, 'c'), 0)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
||||
if (args_has(args, 'r')) {
|
||||
if (c->flags & CLIENT_READONLY)
|
||||
c->flags &= ~CLIENT_READONLY;
|
||||
else
|
||||
c->flags |= CLIENT_READONLY;
|
||||
}
|
||||
if (args_has(args, 'r'))
|
||||
c->flags ^= CLIENT_READONLY;
|
||||
|
||||
tablename = args_get(args, 'T');
|
||||
if (tablename != NULL) {
|
||||
|
|
@ -69,9 +68,9 @@ cmd_switch_client_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
table->references++;
|
||||
key_bindings_unref_table(c->keytable);
|
||||
c->keytable = table;
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
tflag = args_get(args, 't');
|
||||
if (args_has(args, 'n')) {
|
||||
if ((s = session_next_session(c->session)) == NULL) {
|
||||
cmdq_error(cmdq, "can't find next session");
|
||||
|
|
@ -85,48 +84,32 @@ cmd_switch_client_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
} else if (args_has(args, 'l')) {
|
||||
if (c->last_session != NULL && session_alive(c->last_session))
|
||||
s = c->last_session;
|
||||
else
|
||||
s = NULL;
|
||||
if (s == NULL) {
|
||||
cmdq_error(cmdq, "can't find last session");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
} else {
|
||||
if (tflag == NULL) {
|
||||
if ((s = cmd_find_session(cmdq, tflag, 1)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
} else if (tflag[strcspn(tflag, ":.")] != '\0') {
|
||||
if ((wl = cmd_find_pane(cmdq, tflag, &s, &wp)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
} else {
|
||||
if ((s = cmd_find_session(cmdq, tflag, 1)) == NULL)
|
||||
return (CMD_RETURN_ERROR);
|
||||
w = window_find_by_id_str(tflag);
|
||||
if (w == NULL) {
|
||||
wp = window_pane_find_by_id_str(tflag);
|
||||
if (wp != NULL)
|
||||
w = wp->window;
|
||||
}
|
||||
if (w != NULL)
|
||||
wl = winlink_find_by_window(&s->windows, w);
|
||||
}
|
||||
|
||||
if (cmdq->client == NULL)
|
||||
return (CMD_RETURN_NORMAL);
|
||||
|
||||
if (wl != NULL) {
|
||||
if (state->tflag.wl != NULL) {
|
||||
wp = state->tflag.wp;
|
||||
if (wp != NULL)
|
||||
window_set_active_pane(wp->window, wp);
|
||||
session_set_current(s, wl);
|
||||
session_set_current(s, state->tflag.wl);
|
||||
}
|
||||
}
|
||||
|
||||
if (c != NULL && !args_has(args, 'E')) {
|
||||
update = options_get_string(&s->options, "update-environment");
|
||||
environ_update(update, &c->environ, &s->environ);
|
||||
update = options_get_string(s->options, "update-environment");
|
||||
environ_update(update, c->environ, s->environ);
|
||||
}
|
||||
|
||||
if (c->session != NULL && c->session != s)
|
||||
c->last_session = c->session;
|
||||
c->session = s;
|
||||
server_client_set_key_table(c, NULL);
|
||||
status_timer_start(c);
|
||||
session_update_activity(s, NULL);
|
||||
gettimeofday(&s->last_attached_time, NULL);
|
||||
|
|
@ -135,6 +118,7 @@ cmd_switch_client_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
server_check_unattached();
|
||||
server_redraw_client(c);
|
||||
s->curw->flags &= ~WINLINK_ALERTFLAGS;
|
||||
alerts_check_session(s);
|
||||
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -26,22 +26,26 @@
|
|||
* Unbind key from command.
|
||||
*/
|
||||
|
||||
enum cmd_retval cmd_unbind_key_exec(struct cmd *, struct cmd_q *);
|
||||
enum cmd_retval cmd_unbind_key_mode_table(struct cmd *, struct cmd_q *, int);
|
||||
enum cmd_retval cmd_unbind_key_exec(struct cmd *, struct cmd_q *);
|
||||
enum cmd_retval cmd_unbind_key_mode_table(struct cmd *, struct cmd_q *,
|
||||
key_code);
|
||||
|
||||
const struct cmd_entry cmd_unbind_key_entry = {
|
||||
"unbind-key", "unbind",
|
||||
"acnt:T:", 0, 1,
|
||||
"[-acn] [-t mode-table] [-T key-table] key",
|
||||
0,
|
||||
cmd_unbind_key_exec
|
||||
.name = "unbind-key",
|
||||
.alias = "unbind",
|
||||
|
||||
.args = { "acnt:T:", 0, 1 },
|
||||
.usage = "[-acn] [-t mode-table] [-T key-table] key",
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_unbind_key_exec
|
||||
};
|
||||
|
||||
enum cmd_retval
|
||||
cmd_unbind_key_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
int key;
|
||||
key_code key;
|
||||
const char *tablename;
|
||||
|
||||
if (!args_has(args, 'a')) {
|
||||
|
|
@ -50,7 +54,7 @@ cmd_unbind_key_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
key = key_string_lookup_string(args->argv[0]);
|
||||
if (key == KEYC_NONE) {
|
||||
if (key == KEYC_NONE || key == KEYC_UNKNOWN) {
|
||||
cmdq_error(cmdq, "unknown key: %s", args->argv[0]);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
|
@ -59,13 +63,13 @@ cmd_unbind_key_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
cmdq_error(cmdq, "key given with -a");
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
key = KEYC_NONE;
|
||||
key = KEYC_UNKNOWN;
|
||||
}
|
||||
|
||||
if (args_has(args, 't'))
|
||||
return (cmd_unbind_key_mode_table(self, cmdq, key));
|
||||
|
||||
if (key == KEYC_NONE) {
|
||||
if (key == KEYC_UNKNOWN) {
|
||||
tablename = args_get(args, 'T');
|
||||
if (tablename == NULL) {
|
||||
key_bindings_remove_table("root");
|
||||
|
|
@ -95,7 +99,7 @@ cmd_unbind_key_exec(struct cmd *self, struct cmd_q *cmdq)
|
|||
}
|
||||
|
||||
enum cmd_retval
|
||||
cmd_unbind_key_mode_table(struct cmd *self, struct cmd_q *cmdq, int key)
|
||||
cmd_unbind_key_mode_table(struct cmd *self, struct cmd_q *cmdq, key_code key)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
const char *tablename;
|
||||
|
|
@ -108,7 +112,7 @@ cmd_unbind_key_mode_table(struct cmd *self, struct cmd_q *cmdq, int key)
|
|||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
|
||||
if (key == KEYC_NONE) {
|
||||
if (key == KEYC_UNKNOWN) {
|
||||
while (!RB_EMPTY(mtab->tree)) {
|
||||
mbind = RB_ROOT(mtab->tree);
|
||||
RB_REMOVE(mode_key_tree, mtab->tree, mbind);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2013 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2013 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
* Copyright (c) 2013 Thiago de Arruda <tpadilha84@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
|
|
@ -23,6 +23,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "tmux.h"
|
||||
#include "tmate.h"
|
||||
|
||||
/*
|
||||
* Block or wake a client on a named wait channel.
|
||||
|
|
@ -31,11 +32,14 @@
|
|||
enum cmd_retval cmd_wait_for_exec(struct cmd *, struct cmd_q *);
|
||||
|
||||
const struct cmd_entry cmd_wait_for_entry = {
|
||||
"wait-for", "wait",
|
||||
"LSU", 1, 1,
|
||||
"[-L|-S|-U] channel",
|
||||
0,
|
||||
cmd_wait_for_exec
|
||||
.name = "wait-for",
|
||||
.alias = "wait",
|
||||
|
||||
.args = { "LSU", 1, 1 },
|
||||
.usage = "[-L|-S|-U] channel",
|
||||
|
||||
.flags = 0,
|
||||
.exec = cmd_wait_for_exec
|
||||
};
|
||||
|
||||
struct wait_channel {
|
||||
|
|
@ -111,7 +115,7 @@ cmd_wait_for_remove(struct wait_channel *wc)
|
|||
}
|
||||
|
||||
enum cmd_retval
|
||||
cmd_wait_for_exec(struct cmd *self, unused struct cmd_q *cmdq)
|
||||
cmd_wait_for_exec(struct cmd *self, struct cmd_q *cmdq)
|
||||
{
|
||||
struct args *args = self->args;
|
||||
const char *name = args->argv[0];
|
||||
|
|
@ -130,7 +134,7 @@ cmd_wait_for_exec(struct cmd *self, unused struct cmd_q *cmdq)
|
|||
}
|
||||
|
||||
enum cmd_retval
|
||||
cmd_wait_for_signal(unused struct cmd_q *cmdq, const char *name,
|
||||
cmd_wait_for_signal(__unused struct cmd_q *cmdq, const char *name,
|
||||
struct wait_channel *wc)
|
||||
{
|
||||
struct cmd_q *wq, *wq1;
|
||||
|
|
@ -155,12 +159,44 @@ cmd_wait_for_signal(unused struct cmd_q *cmdq, const char *name,
|
|||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
|
||||
#ifdef TMATE
|
||||
void signal_waiting_clients(const char *name)
|
||||
{
|
||||
struct wait_channel *wc, wc0;
|
||||
struct cmd_q *wq, *wq1;
|
||||
|
||||
wc0.name = name;
|
||||
wc = RB_FIND(wait_channels, &wait_channels, &wc0);
|
||||
|
||||
if (wc == NULL || TAILQ_EMPTY(&wc->waiters)) {
|
||||
return;
|
||||
}
|
||||
|
||||
TAILQ_FOREACH_SAFE(wq, &wc->waiters, waitentry, wq1) {
|
||||
TAILQ_REMOVE(&wc->waiters, wq, waitentry);
|
||||
if (!cmdq_free(wq))
|
||||
cmdq_continue(wq);
|
||||
}
|
||||
|
||||
if (!wc->locked) {
|
||||
RB_REMOVE(wait_channels, &wait_channels, wc);
|
||||
free((void*) wc->name);
|
||||
free(wc);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
enum cmd_retval
|
||||
cmd_wait_for_wait(struct cmd_q *cmdq, const char *name,
|
||||
struct wait_channel *wc)
|
||||
{
|
||||
struct client *c = cmdq->client;
|
||||
|
||||
#ifdef TMATE
|
||||
if (!strcmp(name, "tmate-ready") && tmate_session.tmate_env_ready)
|
||||
return (CMD_RETURN_NORMAL);
|
||||
#endif
|
||||
|
||||
if (c == NULL || c->session != NULL) {
|
||||
cmdq_error(cmdq, "not able to wait");
|
||||
return (CMD_RETURN_ERROR);
|
||||
|
|
@ -170,12 +206,11 @@ cmd_wait_for_wait(struct cmd_q *cmdq, const char *name,
|
|||
wc = cmd_wait_for_add(name);
|
||||
|
||||
if (wc->woken) {
|
||||
log_debug("wait channel %s already woken (client %d)", wc->name,
|
||||
c->tty.fd);
|
||||
log_debug("wait channel %s already woken (%p)", wc->name, c);
|
||||
cmd_wait_for_remove(wc);
|
||||
return (CMD_RETURN_NORMAL);
|
||||
}
|
||||
log_debug("wait channel %s not woken (client %d)", wc->name, c->tty.fd);
|
||||
log_debug("wait channel %s not woken (%p)", wc->name, c);
|
||||
|
||||
TAILQ_INSERT_TAIL(&wc->waiters, cmdq, waitentry);
|
||||
cmdq->references++;
|
||||
|
|
|
|||
205
cmd.c
205
cmd.c
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -95,10 +95,12 @@ extern const struct cmd_entry cmd_send_prefix_entry;
|
|||
extern const struct cmd_entry cmd_server_info_entry;
|
||||
extern const struct cmd_entry cmd_set_buffer_entry;
|
||||
extern const struct cmd_entry cmd_set_environment_entry;
|
||||
extern const struct cmd_entry cmd_set_hook_entry;
|
||||
extern const struct cmd_entry cmd_set_option_entry;
|
||||
extern const struct cmd_entry cmd_set_window_option_entry;
|
||||
extern const struct cmd_entry cmd_show_buffer_entry;
|
||||
extern const struct cmd_entry cmd_show_environment_entry;
|
||||
extern const struct cmd_entry cmd_show_hooks_entry;
|
||||
extern const struct cmd_entry cmd_show_messages_entry;
|
||||
extern const struct cmd_entry cmd_show_options_entry;
|
||||
extern const struct cmd_entry cmd_show_window_options_entry;
|
||||
|
|
@ -182,10 +184,12 @@ const struct cmd_entry *cmd_table[] = {
|
|||
&cmd_server_info_entry,
|
||||
&cmd_set_buffer_entry,
|
||||
&cmd_set_environment_entry,
|
||||
&cmd_set_hook_entry,
|
||||
&cmd_set_option_entry,
|
||||
&cmd_set_window_option_entry,
|
||||
&cmd_show_buffer_entry,
|
||||
&cmd_show_environment_entry,
|
||||
&cmd_show_hooks_entry,
|
||||
&cmd_show_messages_entry,
|
||||
&cmd_show_options_entry,
|
||||
&cmd_show_window_options_entry,
|
||||
|
|
@ -344,12 +348,12 @@ cmd_parse(int argc, char **argv, const char *file, u_int line, char **cause)
|
|||
return (NULL);
|
||||
}
|
||||
|
||||
args = args_parse(entry->args_template, argc, argv);
|
||||
args = args_parse(entry->args.template, argc, argv);
|
||||
if (args == NULL)
|
||||
goto usage;
|
||||
if (entry->args_lower != -1 && args->argc < entry->args_lower)
|
||||
if (entry->args.lower != -1 && args->argc < entry->args.lower)
|
||||
goto usage;
|
||||
if (entry->args_upper != -1 && args->argc > entry->args_upper)
|
||||
if (entry->args.upper != -1 && args->argc > entry->args.upper)
|
||||
goto usage;
|
||||
|
||||
cmd = xcalloc(1, sizeof *cmd);
|
||||
|
|
@ -383,21 +387,192 @@ usage:
|
|||
return (NULL);
|
||||
}
|
||||
|
||||
size_t
|
||||
cmd_print(struct cmd *cmd, char *buf, size_t len)
|
||||
static int
|
||||
cmd_prepare_state_flag(char c, const char *target, enum cmd_entry_flag flag,
|
||||
struct cmd_q *cmdq, struct cmd_q *parent)
|
||||
{
|
||||
size_t off, used;
|
||||
int targetflags, error;
|
||||
struct cmd_find_state *fs = NULL;
|
||||
struct cmd_find_state *current = NULL;
|
||||
struct cmd_find_state tmp;
|
||||
|
||||
off = xsnprintf(buf, len, "%s ", cmd->entry->name);
|
||||
if (off + 1 < len) {
|
||||
used = args_print(cmd->args, buf + off, len - off - 1);
|
||||
if (used == 0)
|
||||
off--;
|
||||
if (flag == CMD_NONE ||
|
||||
flag == CMD_CLIENT ||
|
||||
flag == CMD_CLIENT_CANFAIL)
|
||||
return (0);
|
||||
|
||||
if (c == 't')
|
||||
fs = &cmdq->state.tflag;
|
||||
else if (c == 's')
|
||||
fs = &cmdq->state.sflag;
|
||||
|
||||
if (flag == CMD_SESSION_WITHPANE) {
|
||||
if (target != NULL && target[strcspn(target, ":.")] != '\0')
|
||||
flag = CMD_PANE;
|
||||
else
|
||||
off += used;
|
||||
buf[off] = '\0';
|
||||
flag = CMD_SESSION;
|
||||
}
|
||||
return (off);
|
||||
|
||||
targetflags = 0;
|
||||
switch (flag) {
|
||||
case CMD_SESSION:
|
||||
case CMD_SESSION_CANFAIL:
|
||||
case CMD_SESSION_PREFERUNATTACHED:
|
||||
if (flag == CMD_SESSION_CANFAIL)
|
||||
targetflags |= CMD_FIND_QUIET;
|
||||
if (flag == CMD_SESSION_PREFERUNATTACHED)
|
||||
targetflags |= CMD_FIND_PREFER_UNATTACHED;
|
||||
break;
|
||||
case CMD_MOVEW_R:
|
||||
flag = CMD_WINDOW_INDEX;
|
||||
/* FALLTHROUGH */
|
||||
case CMD_WINDOW:
|
||||
case CMD_WINDOW_CANFAIL:
|
||||
case CMD_WINDOW_MARKED:
|
||||
case CMD_WINDOW_INDEX:
|
||||
if (flag == CMD_WINDOW_CANFAIL)
|
||||
targetflags |= CMD_FIND_QUIET;
|
||||
if (flag == CMD_WINDOW_MARKED)
|
||||
targetflags |= CMD_FIND_DEFAULT_MARKED;
|
||||
if (flag == CMD_WINDOW_INDEX)
|
||||
targetflags |= CMD_FIND_WINDOW_INDEX;
|
||||
break;
|
||||
case CMD_PANE:
|
||||
case CMD_PANE_CANFAIL:
|
||||
case CMD_PANE_MARKED:
|
||||
if (flag == CMD_PANE_CANFAIL)
|
||||
targetflags |= CMD_FIND_QUIET;
|
||||
if (flag == CMD_PANE_MARKED)
|
||||
targetflags |= CMD_FIND_DEFAULT_MARKED;
|
||||
break;
|
||||
default:
|
||||
fatalx("unknown %cflag %d", c, flag);
|
||||
}
|
||||
|
||||
log_debug("%s: flag %c %d %#x", __func__, c, flag, targetflags);
|
||||
if (parent != NULL) {
|
||||
if (c == 't')
|
||||
current = &parent->state.tflag;
|
||||
else if (c == 's')
|
||||
current = &parent->state.sflag;
|
||||
} else {
|
||||
error = cmd_find_current(&tmp, cmdq, targetflags);
|
||||
if (error != 0 && ~targetflags & CMD_FIND_QUIET)
|
||||
return (-1);
|
||||
current = &tmp;
|
||||
}
|
||||
|
||||
switch (flag) {
|
||||
case CMD_NONE:
|
||||
case CMD_CLIENT:
|
||||
case CMD_CLIENT_CANFAIL:
|
||||
return (0);
|
||||
case CMD_SESSION:
|
||||
case CMD_SESSION_CANFAIL:
|
||||
case CMD_SESSION_PREFERUNATTACHED:
|
||||
case CMD_SESSION_WITHPANE:
|
||||
error = cmd_find_target(fs, current, cmdq, target,
|
||||
CMD_FIND_SESSION, targetflags);
|
||||
if (error != 0 && ~targetflags & CMD_FIND_QUIET)
|
||||
return (-1);
|
||||
break;
|
||||
case CMD_MOVEW_R:
|
||||
error = cmd_find_target(fs, current, cmdq, target,
|
||||
CMD_FIND_SESSION, CMD_FIND_QUIET);
|
||||
if (error == 0)
|
||||
break;
|
||||
/* FALLTHROUGH */
|
||||
case CMD_WINDOW:
|
||||
case CMD_WINDOW_CANFAIL:
|
||||
case CMD_WINDOW_MARKED:
|
||||
case CMD_WINDOW_INDEX:
|
||||
error = cmd_find_target(fs, current, cmdq, target,
|
||||
CMD_FIND_WINDOW, targetflags);
|
||||
if (error != 0 && ~targetflags & CMD_FIND_QUIET)
|
||||
return (-1);
|
||||
break;
|
||||
case CMD_PANE:
|
||||
case CMD_PANE_CANFAIL:
|
||||
case CMD_PANE_MARKED:
|
||||
error = cmd_find_target(fs, current, cmdq, target,
|
||||
CMD_FIND_PANE, targetflags);
|
||||
if (error != 0 && ~targetflags & CMD_FIND_QUIET)
|
||||
return (-1);
|
||||
break;
|
||||
default:
|
||||
fatalx("unknown %cflag %d", c, flag);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
cmd_prepare_state(struct cmd *cmd, struct cmd_q *cmdq, struct cmd_q *parent)
|
||||
{
|
||||
const struct cmd_entry *entry = cmd->entry;
|
||||
struct cmd_state *state = &cmdq->state;
|
||||
char *tmp;
|
||||
enum cmd_entry_flag flag;
|
||||
const char *s;
|
||||
int error;
|
||||
|
||||
tmp = cmd_print(cmd);
|
||||
log_debug("preparing state for %s (client %p)", tmp, cmdq->client);
|
||||
free(tmp);
|
||||
|
||||
state->c = NULL;
|
||||
cmd_find_clear_state(&state->tflag, NULL, 0);
|
||||
cmd_find_clear_state(&state->sflag, NULL, 0);
|
||||
|
||||
flag = cmd->entry->cflag;
|
||||
if (flag == CMD_NONE) {
|
||||
flag = cmd->entry->tflag;
|
||||
if (flag == CMD_CLIENT || flag == CMD_CLIENT_CANFAIL)
|
||||
s = args_get(cmd->args, 't');
|
||||
else
|
||||
s = NULL;
|
||||
} else
|
||||
s = args_get(cmd->args, 'c');
|
||||
switch (flag) {
|
||||
case CMD_CLIENT:
|
||||
state->c = cmd_find_client(cmdq, s, 0);
|
||||
if (state->c == NULL)
|
||||
return (-1);
|
||||
break;
|
||||
default:
|
||||
state->c = cmd_find_client(cmdq, s, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
s = args_get(cmd->args, 't');
|
||||
log_debug("preparing -t state: target %s", s == NULL ? "none" : s);
|
||||
|
||||
error = cmd_prepare_state_flag('t', s, entry->tflag, cmdq, parent);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
s = args_get(cmd->args, 's');
|
||||
log_debug("preparing -s state: target %s", s == NULL ? "none" : s);
|
||||
|
||||
error = cmd_prepare_state_flag('s', s, entry->sflag, cmdq, parent);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
char *
|
||||
cmd_print(struct cmd *cmd)
|
||||
{
|
||||
char *out, *s;
|
||||
|
||||
s = args_print(cmd->args);
|
||||
if (*s != '\0')
|
||||
xasprintf(&out, "%s %s", cmd->entry->name, s);
|
||||
else
|
||||
out = xstrdup(cmd->entry->name);
|
||||
free(s);
|
||||
|
||||
return (out);
|
||||
}
|
||||
|
||||
/* Adjust current mouse position for a pane. */
|
||||
|
|
|
|||
2
colour.c
2
colour.c
|
|
@ -1,7 +1,7 @@
|
|||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
|
|||
14
compat.h
14
compat.h
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
@ -21,6 +21,9 @@
|
|||
#define __attribute__(a)
|
||||
#endif
|
||||
|
||||
#ifndef __unused
|
||||
#define __unused __attribute__ ((__unused__))
|
||||
#endif
|
||||
#ifndef __dead
|
||||
#define __dead __attribute__ ((__noreturn__))
|
||||
#endif
|
||||
|
|
@ -255,13 +258,18 @@ int unsetenv(const char *);
|
|||
|
||||
#ifndef HAVE_CFMAKERAW
|
||||
/* cfmakeraw.c */
|
||||
void cfmakeraw(struct termios *);
|
||||
void cfmakeraw(struct termios *);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_OPENAT
|
||||
/* openat.c */
|
||||
#define AT_FDCWD -100
|
||||
int openat(int, const char *, int, ...);
|
||||
int openat(int, const char *, int, ...);
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_REALLOCARRAY
|
||||
/* reallocarray.c */
|
||||
void *reallocarray(void *, size_t, size_t size);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETOPT
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2006 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2006 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "compat.h"
|
||||
|
||||
#define Assert(Cond) if (!(Cond)) abort()
|
||||
|
||||
static const char Base64[] =
|
||||
|
|
@ -122,7 +124,7 @@ static const char Pad64 = '=';
|
|||
*/
|
||||
|
||||
int
|
||||
b64_ntop(uint8_t const *src, size_t srclength, char *target, size_t targsize) {
|
||||
b64_ntop(const char *src, size_t srclength, char *target, size_t targsize) {
|
||||
size_t datalength = 0;
|
||||
uint8_t input[3];
|
||||
uint8_t output[4];
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2013 Dagobert Michelsen
|
||||
* Copyright (c) 2013 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2013 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
|
|||
|
|
@ -14,8 +14,6 @@
|
|||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "tmux.h"
|
||||
|
||||
#ifndef HAVE_CLOSEFROM
|
||||
|
||||
#include <sys/types.h>
|
||||
|
|
@ -47,6 +45,8 @@
|
|||
# endif
|
||||
#endif
|
||||
|
||||
#include "tmux.h"
|
||||
|
||||
#ifndef OPEN_MAX
|
||||
# define OPEN_MAX 256
|
||||
#endif
|
||||
|
|
|
|||
110
compat/fgetln.c
110
compat/fgetln.c
|
|
@ -1,43 +1,26 @@
|
|||
/* $NetBSD: fgetln.c,v 1.3 2007/08/07 02:06:58 lukem Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
* All rights reserved.
|
||||
/*
|
||||
* Copyright (c) 2015 Joerg Jung <jung@openbsd.org>
|
||||
*
|
||||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Christos Zoulas.
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of The NetBSD Foundation nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
/*
|
||||
* portable fgetln() version, NOT reentrant
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "tmux.h"
|
||||
|
||||
|
|
@ -45,41 +28,34 @@ char *
|
|||
fgetln(FILE *fp, size_t *len)
|
||||
{
|
||||
static char *buf = NULL;
|
||||
static size_t bufsiz = 0;
|
||||
char *ptr;
|
||||
static size_t bufsz = 0;
|
||||
size_t r = 0;
|
||||
char *p;
|
||||
int c, e;
|
||||
|
||||
|
||||
if (buf == NULL) {
|
||||
bufsiz = BUFSIZ;
|
||||
if ((buf = malloc(bufsiz)) == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fgets(buf, bufsiz, fp) == NULL)
|
||||
if (!fp || !len) {
|
||||
errno = EINVAL;
|
||||
return NULL;
|
||||
|
||||
*len = 0;
|
||||
while ((ptr = strchr(&buf[*len], '\n')) == NULL) {
|
||||
size_t nbufsiz = bufsiz + BUFSIZ;
|
||||
char *nbuf = realloc(buf, nbufsiz);
|
||||
|
||||
if (nbuf == NULL) {
|
||||
int oerrno = errno;
|
||||
free(buf);
|
||||
errno = oerrno;
|
||||
buf = NULL;
|
||||
return NULL;
|
||||
} else
|
||||
buf = nbuf;
|
||||
|
||||
*len = bufsiz;
|
||||
if (fgets(&buf[bufsiz], BUFSIZ, fp) == NULL)
|
||||
return buf;
|
||||
|
||||
bufsiz = nbufsiz;
|
||||
}
|
||||
|
||||
*len = (ptr - buf) + 1;
|
||||
return buf;
|
||||
if (!buf) {
|
||||
if (!(buf = calloc(1, BUFSIZ)))
|
||||
return NULL;
|
||||
bufsz = BUFSIZ;
|
||||
}
|
||||
while ((c = getc(fp)) != EOF) {
|
||||
buf[r++] = c;
|
||||
if (r == bufsz) {
|
||||
if (!(p = reallocarray(buf, 2, bufsz))) {
|
||||
e = errno;
|
||||
free(buf);
|
||||
errno = e;
|
||||
buf = NULL, bufsz = 0;
|
||||
return NULL;
|
||||
}
|
||||
buf = p, bufsz = 2 * bufsz;
|
||||
}
|
||||
if (c == '\n')
|
||||
break;
|
||||
}
|
||||
return (*len = r) ? buf : NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2008 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2013 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||
* Copyright (c) 2013 Nicholas Marriott <nicholas.marriott@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
|
|
|
|||
40
compat/reallocarray.c
Normal file
40
compat/reallocarray.c
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/* $OpenBSD: reallocarray.c,v 1.3 2015/09/13 08:31:47 guenther Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2008 Otto Moerbeek <otto@drijf.net>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "tmux.h"
|
||||
|
||||
/*
|
||||
* This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX
|
||||
* if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW
|
||||
*/
|
||||
#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4))
|
||||
|
||||
void *
|
||||
reallocarray(void *optr, size_t nmemb, size_t size)
|
||||
{
|
||||
if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
|
||||
nmemb > 0 && SIZE_MAX / nmemb < size) {
|
||||
errno = ENOMEM;
|
||||
return NULL;
|
||||
}
|
||||
return realloc(optr, size * nmemb);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue