summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xread-character-from-terminal.bash68
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
12readchar_reset() 12readchar_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
20i() 17i()
@@ -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
165run_test() 168run_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
175with_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
189run_test()
190{
191 with_raw_tty_input head -c3 | sed -nel
192}
193
194run_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