Skip to content

Commit 3c19083

Browse files
committed
Refactor and fix IO#_io_console_stty
* Make `private` not `protected` * Redirection without proc filesystem * Check the result of `stty` command * Fix wrong constant reference
1 parent 6289033 commit 3c19083

1 file changed

Lines changed: 29 additions & 27 deletions

File tree

lib/ffi/io/console/stty_console.rb

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,54 @@
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"
59
end
610

711
warn "io/console on JRuby shells out to stty for most operations" if $VERBOSE
812

913
# Non-Windows assumes stty command is available
1014
class 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

Comments
 (0)