diff options
-rwxr-xr-x | read-character-from-terminal.bash | 68 |
1 files changed, 21 insertions, 47 deletions
diff --git a/read-character-from-terminal.bash b/read-character-from-terminal.bash index 6abd2b6..ea08306 100755 --- a/read-character-from-terminal.bash +++ b/read-character-from-terminal.bash | |||
@@ -11,10 +11,7 @@ cfmakeraw() | |||
11 | 11 | ||
12 | readchar_reset() | 12 | readchar_reset() |
13 | { | 13 | { |
14 | if [ "$readchar_init_stty" ] | 14 | : |
15 | then | ||
16 | stty "$readchar_init_stty" 2>/dev/null | ||
17 | fi | ||
18 | } | 15 | } |
19 | 16 | ||
20 | i() | 17 | i() |
@@ -38,20 +35,17 @@ readchar_init() | |||
38 | { | 35 | { |
39 | [ $$ != $BASHPID ] || return | 36 | [ $$ != $BASHPID ] || return |
40 | 37 | ||
41 | declare -g -a readchar_termopts | 38 | declare -g SOCAT= SOCAT_PID= |
42 | declare -g readchar_init_stty | ||
43 | declare -g SOCAT | ||
44 | declare -g t | 39 | declare -g t |
40 | declare -g -a readchar_termopts | ||
45 | 41 | ||
46 | [ -t 1 ] && t=y || t= | 42 | [ -t 1 ] && t=y || t= |
47 | readchar_init_stty=$(stty --save) | ||
48 | readchar_termopts=( | 43 | readchar_termopts=( |
49 | opost onlcr isig | 44 | opost onlcr isig |
50 | intr undef | 45 | intr undef |
51 | quit undef | 46 | quit undef |
52 | ) | 47 | ) |
53 | 48 | ||
54 | trap 'x readchar_reset' EXIT | ||
55 | trap "i CONT; readchar_SIGCONT" CONT | 49 | trap "i CONT; readchar_SIGCONT" CONT |
56 | for sig in TSTP TTIN TTOU | 50 | for sig in TSTP TTIN TTOU |
57 | do | 51 | do |
@@ -65,7 +59,10 @@ readchar_SIGCONT() | |||
65 | { | 59 | { |
66 | if check_foreground | 60 | if check_foreground |
67 | then | 61 | then |
68 | x cfmakeraw "${readchar_termopts[@]}" | 62 | if [ -t 0 ] |
63 | then | ||
64 | cfmakeraw "${readchar_termopts[@]}" | ||
65 | fi | ||
69 | x kill -CONT $SOCAT_PID 2>/dev/null | 66 | x kill -CONT $SOCAT_PID 2>/dev/null |
70 | else | 67 | else |
71 | x kill -STOP $BASHPID $SOCAT_PID 2>/dev/null | 68 | x kill -STOP $BASHPID $SOCAT_PID 2>/dev/null |
@@ -82,20 +79,27 @@ readchar() | |||
82 | { | 79 | { |
83 | declare -n REPLY="${1:-CHARACTER}" | 80 | declare -n REPLY="${1:-CHARACTER}" |
84 | 81 | ||
85 | if ! check_foreground | 82 | if [ -t 0 ] |
86 | then | 83 | then |
87 | sleep .25 | 84 | if check_foreground |
88 | return | 85 | then |
86 | if ! [ "$SOCAT_PID" ] | ||
87 | then | ||
88 | cfmakeraw "${readchar_termopts[@]}" | ||
89 | fi | ||
90 | else | ||
91 | sleep .25 | ||
92 | return | ||
93 | fi | ||
89 | fi | 94 | fi |
90 | 95 | ||
91 | if ! [ "$SOCAT_PID" ] || ! kill -CONT "$SOCAT_PID" 2>/dev/null | 96 | if ! [ "$SOCAT_PID" ] |
92 | then | 97 | then |
93 | x cfmakeraw "${readchar_termopts[@]}" | ||
94 | exec {SOCAT}< <(trap 'sleep .25' SIGTSTP; socat - -) | 98 | exec {SOCAT}< <(trap 'sleep .25' SIGTSTP; socat - -) |
95 | SOCAT_PID=$! | 99 | SOCAT_PID=$! |
96 | fi | 100 | fi |
97 | 101 | ||
98 | if read -n1 -d '' -r -s -u "$SOCAT" | 102 | if read -n 1 -d '' -r -s -u "$SOCAT" |
99 | then | 103 | then |
100 | if [ "$t" ] | 104 | if [ "$t" ] |
101 | then | 105 | then |
@@ -112,8 +116,7 @@ readchar() | |||
112 | if [ "$REPLY" ] | 116 | if [ "$REPLY" ] |
113 | then | 117 | then |
114 | printf "%s" "$REPLY" | 118 | printf "%s" "$REPLY" |
115 | elif [ "$OUTPUT_NULLS" ] | 119 | else |
116 | then | ||
117 | printf "\0" | 120 | printf "\0" |
118 | fi | 121 | fi |
119 | fi | 122 | fi |
@@ -164,35 +167,6 @@ reader_process() | |||
164 | 167 | ||
165 | run_test() | 168 | run_test() |
166 | { | 169 | { |
167 | enable -f sleep sleep || return | ||
168 | ( | ||
169 | pid=$BASHPID | ||
170 | exec {HEAD1}> >(head -c1; kill -PIPE $pid) | ||
171 | read_chars >&$HEAD1 | ||
172 | ) | ||
173 | } | ||
174 | |||
175 | with_raw_tty_input() | ||
176 | { | ||
177 | enable -f sleep sleep || return | ||
178 | ( | ||
179 | pid=$BASHPID | ||
180 | if [ $# -gt 0 ] | ||
181 | then | ||
182 | exec {CMD}> >("$@"; kill -PIPE $pid 2>/dev/null) | ||
183 | exec >&$CMD | ||
184 | fi | ||
185 | read_chars | ||
186 | ) | ||
187 | } | ||
188 | |||
189 | run_test() | ||
190 | { | ||
191 | with_raw_tty_input head -c3 | sed -nel | ||
192 | } | ||
193 | |||
194 | run_test() | ||
195 | { | ||
196 | reader_process & | 170 | reader_process & |
197 | kill -TSTP %reader_process | 171 | kill -TSTP %reader_process |
198 | bg %reader_process | 172 | bg %reader_process |