diff options
Diffstat (limited to 'src/hijack-prompt.bash')
-rwxr-xr-x | src/hijack-prompt.bash | 167 |
1 files changed, 130 insertions, 37 deletions
diff --git a/src/hijack-prompt.bash b/src/hijack-prompt.bash index f41dd17..6da5888 100755 --- a/src/hijack-prompt.bash +++ b/src/hijack-prompt.bash | |||
@@ -1,49 +1,38 @@ | |||
1 | #!/bin/bash | 1 | #!/bin/bash |
2 | PS4=$'+ L\t$LINENO:\t' | ||
2 | case $- in | 3 | case $- in |
3 | *i* ) | 4 | *i* ) |
4 | set -m | 5 | ;; |
6 | *x* ) | ||
7 | exec bash --init-file "$0" -i -x -s "$@" | ||
5 | ;; | 8 | ;; |
6 | * ) | 9 | * ) |
7 | exec bash --init-file "$0" -i "$@" | 10 | exec bash --init-file "$0" -i -s "$@" |
8 | ;; | 11 | ;; |
9 | esac | 12 | esac |
10 | 13 | ||
11 | unhijack() | 14 | set -mx |
12 | { | ||
13 | case $# in | ||
14 | 0 ) | ||
15 | exec \ | ||
16 | 0<&$HIJACK_0 \ | ||
17 | 1>&$HIJACK_1 \ | ||
18 | 2>&$HIJACK_2 \ | ||
19 | {HIJACK_0}<&- \ | ||
20 | {HIJACK_1}>&- \ | ||
21 | {HIJACK_2}>&- | ||
22 | ;; | ||
23 | * ) | ||
24 | echo "history -d -1; unhijack; ${*@Q}" | ||
25 | ;; | ||
26 | esac | ||
27 | } | ||
28 | 15 | ||
29 | finally() | 16 | source ./src/finally.bash |
30 | { | ||
31 | exec \ | ||
32 | {HIJACK_0}<&0 \ | ||
33 | {HIJACK_1}>&1 \ | ||
34 | {HIJACK_2}>&2 \ | ||
35 | 0< <(unhijack eval "$1") \ | ||
36 | &> /dev/null | ||
37 | { | ||
38 | "${@:2}" | ||
39 | } <&$HIJACK_0 >&$HIJACK_1 2>&$HIJACK_2 | ||
40 | } | ||
41 | 17 | ||
42 | burld_read() | 18 | burld_read() |
43 | { | 19 | { |
44 | sleep 1 | 20 | while r=0; POSIXLY_CORRECT=y read -N1 -p '[hullo? burld?]> ' || r=$? |
45 | read -p '[hullo? burld?]> ' | 21 | do |
46 | echo "Burly ${REPLY:-Burld!}" | 22 | if (( r > 128 )) |
23 | then | ||
24 | sleep .25 | ||
25 | continue | ||
26 | elif [[ -n $REPLY ]] | ||
27 | then | ||
28 | echo "Burly ${REPLY:-Burld!}" | ||
29 | return 0 | ||
30 | else | ||
31 | echo "read returned $r" >&2 | ||
32 | return $r | ||
33 | fi | ||
34 | done | ||
35 | return 1 | ||
47 | } | 36 | } |
48 | 37 | ||
49 | quiet_fg() | 38 | quiet_fg() |
@@ -55,20 +44,124 @@ quiet_bg() | |||
55 | { | 44 | { |
56 | local STDERR | 45 | local STDERR |
57 | { | 46 | { |
58 | eval "$(printf '%q ' "$@") 2>&\$STDERR {STDERR}>&- &" | 47 | eval "$(printf '%q ' "$@") 2>&$STDERR $STDERR>&- &" |
59 | } {STDERR}>&2 2>/dev/null | 48 | } {STDERR}>&2 2>/dev/null |
60 | } | 49 | } |
61 | 50 | ||
62 | ring0() | 51 | ring0() |
63 | { | 52 | { |
64 | PS1="Burly boo\\\$ " | 53 | PS1="Burly ${SIGNAL:=bee}\\\$ " |
54 | } | ||
55 | |||
56 | lifetime() | ||
57 | { | ||
58 | [[ $$ != $BASHPID ]] && trap 'exit 0' INT | ||
59 | sleep "$1" & | ||
60 | if wait -f $! | ||
61 | then | ||
62 | kill "${@:2}" 2>/dev/null | ||
63 | true | ||
64 | else | ||
65 | return $? | ||
66 | fi | ||
67 | } | ||
68 | |||
69 | h() | ||
70 | { | ||
71 | quiet_bg sleep 5 | ||
72 | jobs -x quiet_bg lifetime 3 -INT %% | ||
73 | finally 'ring0' \ | ||
74 | quiet_fg %sleep | ||
75 | } | ||
76 | |||
77 | # Does this work? | ||
78 | g() | ||
79 | { | ||
80 | # lifetime 1 -INT $$ & | ||
81 | { burld_read; kill -INT $$; : reached ; } & | ||
82 | lifetime 3 -STOP $! & | ||
83 | PROMPT_COMMAND='pcmd fg' | ||
84 | fg | ||
85 | } | ||
86 | |||
87 | # Does this work? | ||
88 | g() | ||
89 | { | ||
90 | # lifetime 1 $$ & | ||
91 | { burld_read; kill -INT $$; : reached ; } & | ||
92 | lifetime 3 -INT $$ & disown | ||
93 | finally 'fg' eval 'sleep 3m & wait -f $!' | ||
94 | } | ||
95 | |||
96 | gn() | ||
97 | { | ||
98 | { burld_read; kill -INT $$; : reached ; } & | ||
99 | lifetime 3 -TSTP $! & disown | ||
100 | finally 'fg' fg | ||
101 | } | ||
102 | |||
103 | gp() | ||
104 | { | ||
105 | { burld_read; kill -INT $$; : reached ; } & | ||
106 | trap "finally fg :" SIGINT | ||
107 | lifetime 3 -INT $$ & disown | ||
108 | # finally 'fg' fg | ||
65 | } | 109 | } |
66 | 110 | ||
111 | # Interrupting read that works | ||
67 | f() | 112 | f() |
68 | { | 113 | { |
69 | quiet_bg burld_read | 114 | quiet_bg burld_read |
115 | jobs -x quiet_bg lifetime 3 -INT %% | ||
70 | finally 'ring0' \ | 116 | finally 'ring0' \ |
71 | quiet_fg burld_read | 117 | quiet_fg %burld_read |
118 | } | ||
119 | |||
120 | pcmd() | ||
121 | { | ||
122 | if [ "$PROMPT_COMMAND" ] | ||
123 | then | ||
124 | PROMPT_COMMAND= | ||
125 | "$@" | ||
126 | else | ||
127 | PROMPT_COMMAND="pcmd ${*@Q}" | ||
128 | fi | ||
129 | } | ||
130 | |||
131 | ff() | ||
132 | { | ||
133 | quiet_bg burld_read | ||
134 | jobs -x quiet_bg lifetime 3 -INT %% | ||
135 | pcmd ring0 | ||
136 | quiet_fg %burld_read | ||
137 | } | ||
138 | |||
139 | ring0gg() | ||
140 | { | ||
141 | kill -INT "$1" 2>/dev/null | ||
142 | PS1="Burly ${SIGNAL:=bee}\\\$ " | ||
72 | } | 143 | } |
73 | 144 | ||
145 | gg() | ||
146 | { | ||
147 | quiet_bg burld_read | ||
148 | jobs -x quiet_bg lifetime 3 -INT %% | ||
149 | finally "ring0gg $!" \ | ||
150 | quiet_fg %burld_read | ||
151 | } | ||
152 | |||
153 | DEBUG=y | ||
154 | |||
155 | trap 'SIGNAL=INT; : SIGINT' INT | ||
156 | |||
74 | PS1="[type 'f']\\\$ " | 157 | PS1="[type 'f']\\\$ " |
158 | |||
159 | case "$1" in | ||
160 | '' ) ;; | ||
161 | ff ) | ||
162 | "$1" | ||
163 | ;; | ||
164 | * ) | ||
165 | "$1" | ||
166 | ;; | ||
167 | esac | ||