Use raw block to return tty to proper state

This commit is contained in:
Sean Sullivan 2021-09-06 22:27:43 -07:00
parent 84f4fbf3cf
commit c88f4c0645

View File

@ -101,32 +101,40 @@ class Sandbox
command = [SANDBOX_EXEC, "-f", seatbelt.path, *args] command = [SANDBOX_EXEC, "-f", seatbelt.path, *args]
# Start sandbox in a pseudoterminal to prevent access of the parent terminal. # Start sandbox in a pseudoterminal to prevent access of the parent terminal.
T.unsafe(PTY).spawn(*command) do |r, w, pid| T.unsafe(PTY).spawn(*command) do |r, w, pid|
# Set the PTY's window size to match the parent terminal. write_to_pty = proc {
# Some formula tests are sensitive to the terminal size and fail if this is not set. # Set the PTY's window size to match the parent terminal.
winch = proc do |_sig| # Some formula tests are sensitive to the terminal size and fail if this is not set.
w.winsize = if $stdout.tty? winch = proc do |_sig|
# We can only use IO#winsize if the IO object is a TTY. w.winsize = if $stdout.tty?
$stdout.winsize # We can only use IO#winsize if the IO object is a TTY.
else $stdout.winsize
# Otherwise, default to tput, if available. else
# This relies on ncurses rather than the system's ioctl. # Otherwise, default to tput, if available.
[Utils.popen_read("tput", "lines").to_i, Utils.popen_read("tput", "cols").to_i] # This relies on ncurses rather than the system's ioctl.
[Utils.popen_read("tput", "lines").to_i, Utils.popen_read("tput", "cols").to_i]
end
end end
begin
# Update the window size whenever the parent terminal's window size changes.
old_winch = trap(:WINCH, &winch)
winch.call(nil)
stdin_thread = Thread.new { IO.copy_stream($stdin, w) }
r.each_char { |c| print(c) }
Process.wait(pid)
ensure
stdin_thread&.kill
trap(:WINCH, old_winch)
end
}
if $stdout.tty?
$stdin.raw &write_to_pty
else
write_to_pty.call
end end
# Update the window size whenever the parent terminal's window size changes.
old_winch = trap(:WINCH, &winch)
winch.call(nil)
$stdin.raw! if $stdin.tty?
stdin_thread = Thread.new { IO.copy_stream($stdin, w) }
r.each_char { |c| print(c) }
Process.wait(pid)
ensure
stdin_thread&.kill
$stdin.cooked! if $stdin.tty?
trap(:WINCH, old_winch)
end end
raise ErrorDuringExecution.new(command, status: $CHILD_STATUS) unless $CHILD_STATUS.success? raise ErrorDuringExecution.new(command, status: $CHILD_STATUS) unless $CHILD_STATUS.success?
rescue rescue