11# attempt to call stty; if failure, raise error
2- `stty 2> /dev/null`
3- if $?. exitstatus != 0
2+ module IO ::Console
3+ STTY = %w[ /usr/bin/stty /bin/stty ] . find { |path | File . executable? ( path ) }
4+ end
5+
6+ unless IO ::Console ::STTY &&
7+ system ( IO ::Console ::STTY , out : File ::NULL , err : %i[ child out ] )
48 raise "stty command returned nonzero exit status"
59end
610
711warn "io/console on JRuby shells out to stty for most operations" if $VERBOSE
812
913# Non-Windows assumes stty command is available
1014class IO
11- if RbConfig ::CONFIG [ 'host_os' ] . downcase =~ /linux/ && File . exist? ( "/proc/#{ Process . pid } /fd" )
12- protected def _io_console_stty ( *args )
13- _io_console_stty_error { `stty #{ args . join ( ' ' ) } < /proc/#{ Process . pid } /fd/#{ fileno } ` }
14- end
15- else
16- protected def _io_console_stty ( *args )
17- _io_console_stty_error { `stty #{ args . join ( ' ' ) } ` }
18- end
19- end
20-
21- protected def _io_console_stty_error
15+ private def _io_console_stty ( *args )
2216 # pre-check to catch non-tty filenos we can't stty against anyway
2317 raise Errno ::ENOTTY , inspect if !tty?
2418
25- result = yield
26-
27- case result
28- when /Inappropriate ioctl for device/
29- raise Errno . ENOTTY , inspect
19+ IO . pipe do |re , we |
20+ IO . popen ( [ Console ::STTY , *args , in : fileno , err : we ] , &:read )
21+ ensure
22+ unless $?. success?
23+ we . close
24+ error = re . read
25+ case error
26+ when /Inappropriate ioctl for device/
27+ raise Errno ::ENOTTY , inspect
28+ end
29+ raise "stty command failed: #{ error . chomp } "
30+ end
3031 end
31-
32- result
3332 end
3433
3534 def raw ( *, min : 1 , time : nil , intr : nil )
36- saved = _io_console_stty ( '-g raw' )
35+ saved = _io_console_stty ( '-g' )
36+ _io_console_stty ( 'raw' )
3737 yield self
3838 ensure
39- _io_console_stty ( saved )
39+ _io_console_stty ( saved ) if saved
4040 end
4141
4242 def raw! ( *)
43- stty ( 'raw' )
43+ _io_console_stty ( 'raw' )
4444 end
4545
4646 def cooked ( *)
47- saved = _io_console_stty ( '-g' , '-raw' )
47+ saved = _io_console_stty ( '-g' )
48+ _io_console_stty ( '-raw' )
4849 yield self
4950 ensure
50- _io_console_stty ( saved )
51+ _io_console_stty ( saved ) if saved
5152 end
5253
5354 def cooked! ( *)
@@ -63,10 +64,11 @@ def echo?
6364 end
6465
6566 def noecho
66- saved = _io_console_stty ( '-g' , '-echo' )
67+ saved = _io_console_stty ( '-g' )
68+ _io_console_stty ( '-echo' )
6769 yield self
6870 ensure
69- _io_console_stty ( saved )
71+ _io_console_stty ( saved ) if saved
7072 end
7173
7274 # Not all systems return same format of stty -a output
0 commit comments