I am writing a terminal emulator in ruby using the PTY library. /dev/tty0
is a device file connected to a keyboard. I am spawning the shell like this:
shell = PTY.spawn 'env TERM=ansi COLUMNS=63 LINES=21 sh -i < /dev/tty0'
It mostly works, but when a subprocess is started in the shell, shell[0]
is not outputting the keyboard input to that subprocess. For example: When I send "cat\nasdf"
through shell[1]
, "cat"
comes back through shell[0]
but "asdf"
does not. Why is this happening, and how can I fix it?
Edit:
Here is my code. ChumbyScreen
is an external module controlling the screen of the embedded device I am writing this for (it is called "Chumby"). The write
method puts a character on the screen.
require 'pty'
def handle_escape(io)
actions = 'ABCDEFGHJKSTfmnsulh'
str, action = '', nil
loop do
c = io.read(1)
if actions.include? c
action = c
break
else
str += c
end
end
case action
when 'J'
ChumbyScreen.x = 0
end
end
system '[ -e /dev/tty0 ] || mknod /dev/tty0 c 4 0'
shell = PTY.spawn 'env TERM=ansi COLUMNS=63 LINES=21 sh -i < /dev/tty0'
loop do
c = shell[0].read(1)
if c == "\e"
c2 = shell[0].read(1)
if c2 == '['
handle_escape shell[0]
next
else
c += c2
end
end
ChumbyScreen.write c
end
After reading shodanex's answer, I tried this:
require 'pty'
def handle_escape(io)
actions = 'ABCDEFGHJKSTfmnsulh'
str, action = '', nil
loop do
c = io.read(1)
if actions.include? c
action = c
break
else
str += c
end
end
case action
when 'J'
ChumbyScreen.x = 0
end
end
system '[ -e /dev/tty0 ] || mknod /dev/tty0 c 4 0'
shell = PTY.spawn 'env TERM=ansi COLUMNS=63 LINES=21 sh -i'
Thread.new do
k = open '/dev/tty0', File::RDONLY
loop do
shell[1].write k.read(1)
end
end.priority = 1
loop do
c = shell[0].read(1)
if c == "\e"
c2 = shell[0].read(1)
if c2 == '['
handle_escape shell[0]
next
else
c += c2
end
end
ChumbyScreen.write c
end
It works, but characters I have typed do not show up until I press enter. It must be line buffered somehow - how do I get past this? Also Control-C and Control-D do nothing. I need them to send an eof and terminate a process.