I am writing Terminal Emulator in Ruby using the PTY library. / dev / tty0
is a device file connected to a keyboard. I'm about to open in this way:
shell = PTY.spawn 'env TERM = AC COLUMNS = 63 LINES = 21 sh -i & lt; / Dev>
This works mostly, but when a subprocessation is started in the shell, then shell [0]
the keyboard input to that subprocess Does not output. For example: when I send open [1]
via "cat \ nasdf"
, "cat"
back shell [0]
but "asdf"
does not. Why is this happening and how can I fix it?
Edit :
This is my code ChumbyScreen
is an external module controlling the screen of an embedded device that I am writing it to I am (it is called "kiss"). The write
method places a letter on the screen.
is required 'pty' def handle_escape (IO) verb = 'ABCDEFGJSAPFNNHH' str, action = '', zero loop Do c = io.read (1) if actions.include? C Action = C brake and str + C and end case action when 'J' chamscreen.x = 0 end and system '[-i / did / tte]] || Mknod / dev / tty0 c 4 0 'shell = PTY.spawn' env TERM = AC COLUMNS = 63 LINES = 21 sh -i & lt; / 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 of end ChumbyScreen.write c end
After reading the answer of shodanex, I tried it:
required 'pty 'Def handle_escape (IO) verb =' ABCDEFGJSAPFFCNLL 'SR, action =' ', by null loop C = Io. Reed (1) If the verb contains indes? C Action = C brake and str + C and end case action when 'J' chamscreen.x = 0 end and system '[-i / did / tte]] || Mknod / dev / tty0 c 4 0 'shell = PTY.spawn' env TERM = AC COLUMNS = 63 LINES = 21 sh -i 'thread.new k = open' / dev / tty0 ', file :: RDONI loop shell [ 1]. Write the letter 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 and c + = c2 end-end ChumbyScreen.write c end
This works, but the characters I typed until I press Do not show the records. It should be line buffer in any way - how do I get it past? Control-C and Control-D do not do anything, I need to send them an eof and finish a process.
TTI input mode defaults in line input, so long as you do not output a new line You will not be able to see anything.
I suggest debugging this kind of behavior so that you can see system calls, and for example see if you are blocking waiting for more input and so on. .
When you use '& lt; / Dev / tty0 ', it works, is not it? In fact, what you want is the resonance of the character if you do the following:
shell = PTY.spawn 'env TERM = AC COLUMNS = 63 LINES = 21 sh -i' shell [1 ]. The output ("cat \ nasdf") s = Shell [0] .read (16) puts
and you are using this process:
strace -ff -o test.log -e trace = read, write./testr.rb
In output you will see asdf twice. But if you look at the strase code, you see that cat subprocessed just writes asdf once, and its basic process, i.e. Shell, writes asdf at any time.
Why are two 'asdf' outputs? Because the TTI layer is resizing local, so when you write something in the shell, it goes to the PTI and PTI driver:
- Write it in the slur side of TTI
- Echo the Master Side on it.
What happens when you sh -i & lt; Do / dev / tty0
? The character coming from the keyboard echoed in / dev / tty0, not on the shell output.
Shell is not echoing, TTI is layer, so what do you want to do (take it as a phishing code, I'm not capable of Ruby):
< Emulate terminal behavior with code> # pty shell = PTY.spawn 'env TERM = ANI COLUMNS = 63 LINES = 21 sh - I' keyboard = open (/ dev / tty0) input = keyboard.read () shell [1]. Write [input] opens [0] .read (...)
Now, if you want something interactive, you need to configure / dev / tty0 in raw mode Need to know, and choose to know Do that when you can read without blocking, and when the data is available for output.
Configure tty in raw mode, you
stty -f / dev / tty0 -cooked
Comments
Post a Comment