How are tty, pty, xterm and user process working together? - tty

I'm reading The TTY demystified, trying to get some understanding about tty, pty.
After reading the first half. I'm not getting the complete picture of how the whole thing is working when I'm type some commands into an xterm or ssh.
Below is the picture visualizing my understanding, I don't know if it's correct or not, please help verify.
when I type a command on the keyboard
keyboard ->tty->xterm->pty(master)->pty(slave)->user processes
(the purple line)
when a user process generates some output
user processes->pty(slave)->pty(master)->xterm->tty->display
(the blue line)

The diagram seems confused with regard to the box for "tty":
a pseudo-terminal has devices that might be named "tty" and "pty" (in the pre-Unix98 configuration). The /dev-entry for tty corresponds to the pseudo-terminal master.
xterm reads keystrokes as X events via the X server from whatever the keyboard device happens to be.

Related

How to detect xterm resize in-band

I'm looking for a way to get resize events on an xterm as an alternative to the winch signal. I need to get a signal for the xterm resize that is remote compatible, that is, could be used over a serial line/telnet/ssh/whatever. The winch signal is only for local machine tasks.
I know that vi/curses can do this because I have tried ssh and use vi to edit a file, and it responds to resizing of the window.
So after a bit of research, it does seem there is no in-band method for this. I don't think it would be difficult to add. You have two sides to a connection, ssh, serial or whatever, let's say A and B where A is on the host and B is the remote. To get behavior equivalent to a local windowed task, I would say at least two things are essential:
Mouse movement/button messaging.
Window resize messaging.
The second, can be a two step process. If the B task gets an alert that the window size has changed, it can use in band queries to determine what the new size is, using the (perhaps infamous) method of setting the cursor to the end of an impossibly large screen and then reading the actual location of the cursor that results, then restoring the location, all done with standard in-band controls.
Why care about in-band vs. out of band? Well, nobody cares now :-), but serial lines used to be quite popular, and in-band, that is, actual escape sequences sent down the line are going to work, but telnet or ssh "out of band" communication is not.
It would not be difficult to add, a local program that shims the ssh or telnet, or even xterm itself, can get the winch message and change that to an escape alert to the B side. Here the mouse messaging is instructive. The messages consist of two actions:
The B side must enable such messages, so that the A side won't send unknown escapes to it.
The A side must have an escape to signify winch.
Thus a new escape from B to A, and one from A to B.
I'm actually fairly satisfied with winch. What was wanted is to have the same capabilities as vi/curses (based on my observation). This kind of support is already far better than Windows, which (as far as I know) implements none of this remote side support.

What is the relationship between framebuffer, VT, and tty?

I'm now studying what is the mechanism behind Ctrl+Alt+F1~F7.
I found some infomation talk about framebuffer, VT, and tty. I know framebuffer is an anstraction to graphic card manipulation and tty(and pts) is something a program interact with. I also find some people talking about VT(virtual terminal), but I don't know what is the relationship between them.
After searching on the web, I made a figure.
I think a VT is a set of monitor and keyboard. If I want to use many tty in one set(one VT), I have to switch between ttys because I only have one monitor to show them. This is VT Swich. But what is VT actually be? A driver, a module, or something else?
I guess if I have two set of monitors and keyboards connect to my computer, I can group them to form two VTs. And I can show my tty1 in monitor1 and control it use keyboard1, and tty2 with monitor2 and keyboard2. I can do VT Switch in both VT, too. Is that true?
And I think I can view framebuffer(fbcon + fbdev) as a graphic card driver, but it is design for console, not for general purpose(proprietary drivers).
Also, there are some special files under /dev
/dev/tty* and /dev/pts/* are for tty
echo can send input to the tty, and cat can recieve output from the tty.
/dev/vcs* are for screen of VT
cat can get the text in the screen, but use it under X get all zero(not empty).
/dev/fb* are for framebuffer
cat can get the whole pixel in the screen, but use it under X get all zero(not empty). I heard that X server doesn't use framebuffer, so what does it use?
Please tell me where I am wrong.
Correct tty and pty are terminals. but there is small difference. pty is pseudo terminals. open a terminal type tty will return pts terminal. tty are generally physical if you have used embedded linux you can redirect linux console to different tty which are uart terminals. if you use a 9 pin uart cable. then you can use ttyX.
vcs are differant screens were used pre X-Server erra. or now in server where X server( or even Wayland Server) is not installed. in run level 3 and 5. to try use CTRL + ALT + F3 to access /dev/vc3. you can echo and cat simmilarly.
frame buffer is part of Graphic subsystem its not supposed to be used with cat. It is matrix. its abstraction over any screen connected. to be used by graphical drivers and applications.

How can I start a bash on a specific /dev/ttyX (or /dev/pts/X) device?

-- Real device --
Let's say I an UART cable on /dev/ttyACM0 (and there is another computer connected to the other end of the cable), how can I start a bash session on that /dev/ttyACM0 device? So my other computer would be able to execute bash commands?
-- Pseudo terminal --
Another example, let's say I opened cutecom or minicom in device /dev/ptmx, it will create a corresponding /dev/pts/X device. How can I start a bash session to run on the created /dev/pts/X?
If I understand correct, it doesn't matter to bash (or getty) if it is running on a real or pseudo terminal. So I think that GUI terminals (like xterm) read /dev/ptmx and start a bash on the corresponding /dev/pts/X, if this is true, then I should be able to do the same, how can I accomplish that? Or is my understanding of it wrong?
fork() a child process. Open the serial device or pseudotty and dup2() it to fd's 0, 1 and 2. execv() your preferred shell.

Use serial-console as display, but computer keyboard for standard-input

I have a 40x7 VFD that functions as a serial terminal. It has a dedicated keypad that provides hex-entry, however, I would like to use a keyboard for the standard input. Basically, I want to be able to use the VFD as a display for a Linux bash prompt, but use the keyboard connected to the computer as the means of input. Instead of connecting a monitor, the serial terminal will be the monitor. I can get the login prompt displayed on the VFD with agetty, but since it only has hex-entry, how can I change where the system is looking for standard input?
Thanks,
Core_Module
I think the best method would be to create a pseudo terminal. In doing so you create a fake terminal device with a /dev/pts/[n] name that acts like a real input/output device. A program could connect the console (keyboard) as input and the VFD as output and send and receive that data over the pseudo device. You can then point agetty at the /dev/pts/[0] device instead of a /dev/ttyS[n] device. Some ideas on doing this can be found in many tutorials online. From the link:
A pseudo-terminal is a pair of character mode devices also called pty. One is master and the other is slave and they are connected with a bidirectional channel. Any data written on the slave side is forwarded to the output of the master side. Conversely, any data written on the master side is forwarded to the output of the slave.
I found another StackOverflow question that may also be of assistance. See this link. It could be adapted to suit your needs.

How to read from STDIN_FILENO even if terminal is closed?

Im trying to code a program in Linux to read every input from keyboard, but using STDIN_FILENO it only reads those entered in the terminal. What I want is during execution it should read keyboard even if the terminal is closed.
STDIN_FILENO is just a helper macro.
From stdin you recieve stream of bytes that are passed to your program, they doesnt neccessary come from terminal - also can from a file, etc. It's not capturing keyboard. The terminal is capturing keyboard and then passes entered data to your program's stdin.
In order to capture keyboard you will need some other method of receiving events. I guess you are running GUI aka X server; Normally applications create windows and receive events related to them. In order to capture all keyboard events, you will have to go more low-level. Take a look at xlib which should be sufficient for you, even though it might not be.

Resources