Originally, "tty" had two definitions: the hardware (now the emulator) and the driver (interfaced through /dev/pty* or /dev/tty*).
The hardware/emulator was/is responsible for:
- Taking a stream of data and presenting it; this included interpreting control sequences like "move cursor left", "blinking cursor", "clear-screen" although these control sequences were often different among manufacturers.
- Sending keycodes for keys typed by the user; most of these were standard ASCII characters, but some terminals sent propriety keycodes for even standard keys.
The 'tty' driver was responsible for:
- Managing the buffering, in raw or canonical mode; for example, buffering a line of characters until Enter is pressed.
- Managing the control flow; e.g. being able to stop/continue with Cntl-s/Cntl-q.
- Translating propriety keycodes to standard ASCII, where applicable.
- Intercepting certain control characters (like Cntl-c and Backspace) and processing them appropriately (send SIGINT on a Cntl-c or signal an EOF on Cntl-d.
- Canonical display of characters, for example, if
echo
is turned off, then do not send feedback (character typed) back to the terminal.
The terminfo and termcap databases managed what terminal control characters should be sent for an operation (like 'clear-screen'). These control sequences were/are not interpreted by the driver, but by the hardware/emulator.
On UNIX, a tty (like many other things) appears as a file. Data written to the tty device goes to the terminal and data coming from the terminal is available for reading on the tty.
If the tty is a hardware serial port, then data written to it gets sent on the wire and data coming from the wire appears on the tty.
If the tty is a machine's video console then data written to it gets displayed on the screen and data coming from the keyboard appears on the tty.
If the tty is a pseudo-tty (virtual terminal) connected to an X terminal emulator such as gnome-terminal
then data written to it gets delivered to the X terminal emulator software and in turn gets shown in a window, while data typed into that window is available for reading on the virtual terminal. The software is said to be connected to the "master" end of the pseudo-terminal. Real terminals don't have a "master" end because there's a real device behind them (like the serial port), not a virtual device implemented by a piece of software.
So you can see already that it wouldn't make any sense to ask a X terminal emulator to operate on an arbitrary tty device such as /dev/ttyS0
(a real serial port, on Linux). It must be a pseudo-tty.
But can the terminal emulator choose the numeric ID of the pseudo-terminal device that it uses? In principle, it would be possible for a kernel to permit this, but in fact the kernel interface for allocating a new pseudo-terminal does not support it: the kernel makes it own choice. (In the SysV model pesudo-terminals are created by opening a special device called /dev/ptmx
and the lowest-numbered available pseudo-terminal device is automatically allocated.)
But: why would you need to choose the number of the pseudo-terminal device that gets allocated? The kernel chooses an unused one that's guaranteed to be available and usable. Do you have a reason why you'd prefer if it chose a different one?
As to you other question:
I saw a lot of tty files in /dev and a lot of pts files in /dev/pts/ I don't know why there are so many of them. Are they all being used?
It depends on the system. On some systems, all possible pseudo-terminal devices are pre-created in /dev/pts
or /dev
, whether they are in use or not. On others, the device nodes only exist if the pseudo-terminal is in use. You say you are using Ununbu, which uses Linux, which is the latter type. So, yes, all of the devices nodes you see in /dev/pts
are presently in use.
But for temporary access, it is not very convenient. I want to use socat to forward a tty or pty to client. Then client can start a terminal with that pty or tty.
If you want socat
or any other piece of software to connect to the master end of a pseudo-terminal, then you need for that software to specifically support doing that. But you're in luck because socat
does. For example, if I run:
socat PTY,link=/tmp/socat.pty TCP-LISTEN:2222 &
sleep 1 && ( setsid bash ) </tmp/socat.pty >/tmp/socat.pty 2>&1
I can get a shell by connecting to port 2222 from somewhere else. Very dangerous from a security point of view!!!
Best Answer
To build an interactive application you can open
/dev/tty
, it will return a file descriptor to the controlling terminal:You can use it instead of
STDIN_FILENO
orSTDOUT_FILENO
(those could be redirected to something different than the terminal when the program is started).Here is some example:
When invoked with
./test >out
, it should print the hello message on the terminal and something likefd: 3
in theout
file.