|
AquilaOS documentation
How it works, and its code
|
The terminal layer: the line discipline, and job control. More...
#include <core/system.h>#include <core/arch.h>#include <sys/sched.h>#include <dev/tty.h>#include <sys/uaccess.h>#include <sys/signal.h>#include <aquila/fcntl.h>Go to the source code of this file.
Macros | |
| #define | IS_CC(tty, c, cc) |
Functions | |
| static void | tty_echo (struct tty *tty, char c) |
| Echoes a character, a control character as ^X. | |
| static void | tty_erase (struct tty *tty) |
| Erases the last character of the line being edited, on the screen too with ECHOE. | |
| static void | tty_deliver (struct tty *tty) |
| Hands the line being edited to the readers. | |
| static int | tty_signal (struct tty *tty, char c) |
| Handles a signal character (with ISIG): the foreground group gets the signal. | |
| ssize_t | tty_master_write (struct tty *tty, size_t size, void *buf) |
| Takes input from the terminal's device (the keyboard, a UART, or a pseudo-terminal's master), and puts it through the line discipline to what programs read. | |
| int | tty_eof (struct tty *tty) |
| Says whether a read that found nothing to return should return 0 at once: at an end-of-file (VEOF at the start of a line), or with VMIN and VTIME both 0 in non-canonical mode. | |
| uint64_t | tty_read_timeout (struct tty *tty) |
| Says how long a read waits for input: VTIME tenths of a second with VMIN 0 in non-canonical mode, otherwise until there is some. | |
| int | tty_can_read (struct tty *tty, size_t buffered) |
| Says whether the terminal is readable, for select() and poll(): there is input, or an end-of-file. | |
| int | tty_background (struct tty *tty, int sig) |
| Stops a background process that reads the terminal, writes it or changes it: if the current process is of the terminal's session but not of its foreground group, its group gets the signal and stops until it is continued in the foreground. | |
| static int | tty_out (struct tty *tty, const char *s, size_t n) |
| Sends n bytes to the device. | |
| ssize_t | tty_slave_write (struct tty *tty, size_t size, void *_buf) |
| Takes what programs write to the terminal, and sends it to the device through output processing (OPOST, POSIX's output modes): NL as CR NL (ONLCR), CR as NL (OCRNL), no CR in the first column (ONOCR), and NL returning the carriage too (ONLRET). | |
| static void | tty_release (struct tty *tty) |
| Frees a terminal's memory. | |
| static int | tty_wait_start (struct tty *tty) |
| Waits while the terminal's output is stopped (IXON). | |
| ssize_t | tty_write_iobuf (struct tty *tty, struct iobuf *io, ttyio write) |
| Writes to a terminal from an iobuf (user memory), to either side: a piece at a time through a kernel buffer, the iobuf moved on only as far as was taken. | |
| int | tty_ioctl (struct tty *tty, int request, void *argp) |
| Handles a terminal's ioctl()s: its modes (TCGETS, TCSETS, ...), flushing, its session and foreground group, its window size, and becoming the controlling terminal (TIOCSCTTY). | |
| int | tty_new (struct proc *proc, size_t buf_size, ttyio master, ttyio slave, void *p, struct tty **ref) |
| Makes a new terminal, with the default modes (canonical, echo, signals, ICRNL, IXON, OPOST with ONLCR) and the usual special characters. | |
| void | tty_open (struct tty *tty, struct file *file) |
| Handles a terminal device being opened: it becomes the controlling terminal of a session leader that has none (unless O_NOCTTY), if no session has it already. | |
| void | tty_hangup (struct tty *tty) |
| Hangs up a controlling terminal, when its session ends (its leader exited) or the terminal goes away: its foreground group gets SIGHUP (and SIGCONT, in case it was stopped), and the terminal belongs to no session anymore. | |
| void | tty_flush (struct tty *tty, int which) |
| Drops a terminal's input (TCIFLUSH, TCIOFLUSH): the line being edited, what the device holds for readers, and the pending end-of-files. | |
| int | tty_free (struct tty *tty) |
| Ends a terminal: it is hung up, and freed. | |
The terminal layer: the line discipline, and job control.
Every terminal (a virtual terminal, a serial port, a pseudo-terminal) has a struct tty between its device's two sides. The master side is the device's (the keyboard, the UART, the program on a pseudo-terminal's master), the slave side the programs that read and write the terminal. Input from the master goes through the line discipline: translation, flow control, signal characters, and in canonical mode line editing, with what is typed echoed. Output from the programs goes through output processing (OPOST) to the device. The terminal also belongs to a session, whose foreground process group may read and write it; the other groups are stopped when they try (SIGTTIN, SIGTTOU). See docs/kernel/devices.md.
Definition in file generic.c.
| #define IS_CC | ( | tty, | |
| c, | |||
| cc ) |
| int tty_background | ( | struct tty * | tty, |
| int | sig ) |
Stops a background process that reads the terminal, writes it or changes it: if the current process is of the terminal's session but not of its foreground group, its group gets the signal and stops until it is continued in the foreground.
Writes are only stopped with TOSTOP, which the callers check.
| tty | the terminal |
| sig | SIGTTIN for a read, SIGTTOU for a write or a change |
Definition at line 259 of file generic.c.
References curproc, ERESTARTSYS, tty::fg, NULL, proc::pgrp, pgrp_orphaned(), pgroup::session, tty::session, SIG_IGN, proc::sigaction, proc::sigmask, signal_pgrp_send(), and tty_background().
Referenced by pts_read(), pts_write(), tty_background(), tty_ioctl(), uart_read(), uart_write(), vt_read(), and vt_write().
Says whether the terminal is readable, for select() and poll(): there is input, or an end-of-file.
With VMIN and VTIME 0 a read doesn't wait either, but it isn't readable without input, as on Linux and the BSDs: a program that waits for input in select() would otherwise never sleep.
| tty | the terminal |
| buffered | how many bytes the device holds for readers |
Definition at line 240 of file generic.c.
References tty::eof, and tty_can_read().
Referenced by pts_can_read(), tty_can_read(), uart_can_read(), and vt_can_read().
|
static |
Hands the line being edited to the readers.
Definition at line 64 of file generic.c.
References tty::cook, tty::pos, tty::slave_write, and tty_deliver().
Referenced by tty_deliver(), and tty_master_write().
|
static |
Echoes a character, a control character as ^X.
Definition at line 33 of file generic.c.
References tty_echo(), and tty_slave_write().
Referenced by tty_echo(), tty_master_write(), and tty_signal().
| int tty_eof | ( | struct tty * | tty | ) |
Says whether a read that found nothing to return should return 0 at once: at an end-of-file (VEOF at the start of a line), or with VMIN and VTIME both 0 in non-canonical mode.
An end-of-file is used up.
| tty | the terminal |
Definition at line 200 of file generic.c.
References tty::eof, tty::tios, and tty_eof().
Referenced by pts_eof(), tty_eof(), uart_file_eof(), and vt_file_eof().
|
static |
Erases the last character of the line being edited, on the screen too with ECHOE.
Definition at line 47 of file generic.c.
References tty::cook, tty::pos, tty::tios, tty_erase(), and tty_slave_write().
Referenced by tty_erase(), and tty_master_write().
| void tty_flush | ( | struct tty * | tty, |
| int | which ) |
Drops a terminal's input (TCIFLUSH, TCIOFLUSH): the line being edited, what the device holds for readers, and the pending end-of-files.
Output isn't kept anywhere, so there is none to drop.
| tty | the terminal |
| which | TCIFLUSH, TCOFLUSH or TCIOFLUSH |
Definition at line 691 of file generic.c.
References tty::eof, tty::input_flush, tty::pos, and tty_flush().
Referenced by tty_flush(), and tty_ioctl().
| int tty_free | ( | struct tty * | tty | ) |
Ends a terminal: it is hung up, and freed.
If writers are waiting for its output to start again, they are woken up instead, and the last one frees it.
| tty | the terminal |
Definition at line 718 of file generic.c.
References tty::gone, tty::start_wait, tty::start_waiters, tty::stopped, tty_free(), tty_hangup(), tty_release(), and waitq_wakeup().
Referenced by pty_free(), pty_new(), and tty_free().
| void tty_hangup | ( | struct tty * | tty | ) |
Hangs up a controlling terminal, when its session ends (its leader exited) or the terminal goes away: its foreground group gets SIGHUP (and SIGCONT, in case it was stopped), and the terminal belongs to no session anymore.
| tty | the terminal |
Definition at line 668 of file generic.c.
References session::ctty, tty::fg, NULL, tty::session, signal_pgrp_send(), and tty_hangup().
Referenced by proc_kill(), tty_free(), and tty_hangup().
| int tty_ioctl | ( | struct tty * | tty, |
| int | request, | ||
| void * | argp ) |
Handles a terminal's ioctl()s: its modes (TCGETS, TCSETS, ...), flushing, its session and foreground group, its window size, and becoming the controlling terminal (TIOCSCTTY).
| tty | the terminal |
| request | the request |
| argp | its argument, in user memory (or the value itself, for TCFLSH) |
Definition at line 455 of file generic.c.
References session::ctty, curproc, tty::fg, session::leader, NULL, pgroup::pgid, session::pgps, queue_for, tty::session, session::sid, tty::start_wait, tty::stopped, tty::tios, tty_background(), tty_flush(), tty_ioctl(), waitq_wakeup(), and tty::ws.
Referenced by pty_ioctl(), tty_ioctl(), uart_ioctl(), and vt_ioctl().
Takes input from the terminal's device (the keyboard, a UART, or a pseudo-terminal's master), and puts it through the line discipline to what programs read.
Canonical mode collects lines, with erase (VERASE), kill (VKILL) and end-of-file (VEOF); otherwise, the programs get the characters as they come.
| tty | the terminal |
| size | the input's size, in bytes |
| buf | the input |
Definition at line 111 of file generic.c.
References tty::cook, tty::eof, IS_CC, tty::pos, tty::size, tty::slave_write, tty::start_wait, tty::stopped, tty::tios, tty_deliver(), tty_echo(), tty_erase(), tty_master_write(), tty_signal(), and waitq_wakeup().
Referenced by ptm_write(), tty_master_write(), uart_receive_handler(), and vt_input_to().
| int tty_new | ( | struct proc * | proc, |
| size_t | buf_size, | ||
| ttyio | master, | ||
| ttyio | slave, | ||
| void * | p, | ||
| struct tty ** | ref ) |
Makes a new terminal, with the default modes (canonical, echo, signals, ICRNL, IXON, OPOST with ONLCR) and the usual special characters.
| proc | the process making it (not used) |
| buf_size | the size of its line buffer, or 0 for TTY_BUF_SIZE |
| master | how the terminal sends output to its device |
| slave | how the terminal hands input to its readers |
| p | the device's own data, for those two |
| ref | set to the new terminal |
Definition at line 584 of file generic.c.
References tty::col, tty::cook, kfree(), kmalloc(), M_ZERO, tty::master_write, tty::nl_owed, NULL, tty::p, tty::pos, tty::size, tty::slave_write, tty::tios, TTY_BUF_SIZE, tty_new(), and tty::ws.
Referenced by pty_new(), tty_new(), uart_setup(), and vt_setup().
Handles a terminal device being opened: it becomes the controlling terminal of a session leader that has none (unless O_NOCTTY), if no session has it already.
Opening /dev/console doesn't do it, as on Linux: init writes there, and would otherwise take the terminal that is also the console (the first virtual terminal, or the UART) from the session that a getty starts on it.
| tty | the terminal |
| file | the file being opened |
Definition at line 646 of file generic.c.
References session::ctty, curproc, DEV, tty::fg, file::flags, session::leader, tty::session, and tty_open().
Referenced by pts_open(), tty_open(), uart_file_open(), and vt_file_open().
Sends n bytes to the device.
Returns whether it took all of them.
Definition at line 280 of file generic.c.
References tty::master_write, and tty_out().
Referenced by tty_out(), and tty_slave_write().
Says how long a read waits for input: VTIME tenths of a second with VMIN 0 in non-canonical mode, otherwise until there is some.
| tty | the terminal |
Definition at line 221 of file generic.c.
References tty::tios, and tty_read_timeout().
Referenced by pts_read_timeout(), tty_read_timeout(), uart_read_timeout(), and vt_read_timeout().
|
static |
Frees a terminal's memory.
Definition at line 704 of file generic.c.
References tty::cook, kfree(), and tty_release().
Referenced by tty_free(), tty_release(), and tty_wait_start().
|
static |
Handles a signal character (with ISIG): the foreground group gets the signal.
Returns whether c was one.
Definition at line 74 of file generic.c.
References tty::fg, IS_CC, tty::pos, signal_pgrp_send(), tty::tios, tty_echo(), tty_signal(), and tty_slave_write().
Referenced by tty_master_write(), and tty_signal().
Takes what programs write to the terminal, and sends it to the device through output processing (OPOST, POSIX's output modes): NL as CR NL (ONLCR), CR as NL (OCRNL), no CR in the first column (ONOCR), and NL returning the carriage too (ONLRET).
The column is tracked for them.
| tty | the terminal |
| size | the output's size, in bytes |
| _buf | the output |
Definition at line 297 of file generic.c.
References tty::col, tty::master_write, tty::nl_owed, tty::tios, tty_out(), and tty_slave_write().
Referenced by pts_write(), tty_echo(), tty_erase(), tty_signal(), tty_slave_write(), tty_write_iobuf(), uart_write(), and vt_write().
|
static |
Waits while the terminal's output is stopped (IXON).
Returns 0 once it starts again, -ERESTARTSYS for a signal, or -EIO if the terminal went away meanwhile (and its last waiter then frees it).
Definition at line 376 of file generic.c.
References tty::gone, tty::start_wait, tty::start_waiters, tty::stopped, tty_release(), tty_wait_start(), and waitq_sleep().
Referenced by tty_wait_start(), and tty_write_iobuf().
Writes to a terminal from an iobuf (user memory), to either side: a piece at a time through a kernel buffer, the iobuf moved on only as far as was taken.
| tty | the terminal |
| io | what to write |
| write | the side: tty_master_write (input, from a pseudo-terminal's master) or tty_slave_write (a program's output) |
Definition at line 408 of file generic.c.
References iobuf_peek(), iobuf_skip(), MIN, iobuf::resid, tty::stopped, tty_slave_write(), tty_wait_start(), and tty_write_iobuf().
Referenced by ptm_write(), pts_write(), tty_write_iobuf(), uart_write(), and vt_write().