stdlib_libraries/pseudo_terminals.rb
tests/_examples/stdlib_libraries/pseudo_terminals.rb in the metorex repository.
# PTY runs a program with a terminal of its own and opens terminal pairs, and
# PTY.check reports on a child without waiting for it.
require("pty")
p(PTY.singleton_methods.sort)
p(PTY::ChildExited.superclass)
reader, writer, pid = PTY.spawn("printf 'hello\\n'; exit 3")
p([reader.class, writer.class, pid.class])
p(reader.equal?(writer))
p(reader.gets)
Process.wait(pid)
p($?.exitstatus)
p(PTY.check(pid))
controlling, terminal = PTY.open
p([controlling.class, terminal.class])
p(terminal.tty?, controlling.tty?)
p(terminal.path.start_with?("/dev/"))
terminal.write("typed\n")
p(controlling.readpartial(100))
controlling.write("back\n")
p(terminal.gets)
controlling.close
terminal.close
PTY.open { |pair| p(pair.map(&:class)) }
p(PTY.open { :answer })
child = fork { sleep 5 }
p(PTY.check(child))
Process.kill(:KILL, child)
status = nil
status = PTY.check(child) until status
p(status.class, status.signaled?)
PTY.spawn("echo", "block form") { |output, _input, spawned| p(output.gets); Process.wait(spawned) }
greeting = PTY.spawn({ "GREETING" => "hi" }, "echo $GREETING")
p(greeting[0].gets)
Process.wait(greeting[2])
ending = PTY.spawn("exit 7")[2]
begin
loop { PTY.check(ending, true) }
rescue PTY::ChildExited => error
p(error.status.exitstatus)
p(error.message == "pty - exited: #{ending}")
end
Output:
[:check, :getpty, :open, :spawn]
RuntimeError
[File, File, Integer]
false
"hello\r\n"
3
nil
[IO, File]
true
true
true
"typed\r\n"
"back\n"
[IO, File]
:answer
nil
Process::Status
true
"block form\r\n"
"hi\r\n"
7
true