sandbox: handle SIGTTOU and SIGTTIN to avoid hangs

This commit is contained in:
Bo Anderson 2022-01-25 16:22:00 +00:00
parent c40b2baf9e
commit 8eb4756d3e
No known key found for this signature in database
GPG Key ID: 3DB94E204E137D65

View File

@ -115,17 +115,25 @@ class Sandbox
end
write_to_pty = proc do
# Don't hang if stdin is not able to be used - throw EIO instead.
old_ttin = trap(:TTIN, "IGNORE")
# 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) }
stdin_thread = Thread.new do
IO.copy_stream($stdin, w)
rescue Errno::EIO
# stdin is unavailable - move on.
end
r.each_char { |c| print(c) }
Process.wait(pid)
ensure
stdin_thread&.kill
trap(:TTIN, old_ttin)
trap(:WINCH, old_winch)
end
@ -134,7 +142,13 @@ class Sandbox
# mode while we copy the input/output of the process spawned in the
# PTY. After we've finished copying to/from the PTY process, io.raw
# will restore the stdin TTY to its original state.
begin
# Ignore SIGTTOU as setting raw mode will hang if the process is in the background.
old_ttou = trap(:TTOU, "IGNORE")
$stdin.raw(&write_to_pty)
ensure
trap(:TTOU, old_ttou)
end
else
write_to_pty.call
end