TTY Struct¶
struct tty_struct is allocated by the TTY layer upon the first open of the TTY
device and released after the last close. The TTY layer passes this structure
to most of struct tty_operation’s hooks. Members of tty_struct are documented
in TTY Struct Reference at the bottom.
Initialization¶
-
void
tty_init_termios(struct tty_struct *tty)¶ helper for termios setup
Parameters
struct tty_struct *ttythe tty to set up
Description
Initialise the termios structure for this tty. This runs under the
tty_mutex currently so we can be relaxed about ordering.
Name¶
-
const char *
tty_name(const struct tty_struct *tty)¶ return tty naming
Parameters
const struct tty_struct *ttytty structure
Description
Convert a tty structure into a name. The name reflects the kernel naming policy and if udev is in use may not reflect user space
Locking: none
Reference counting¶
-
struct tty_struct *
tty_kref_get(struct tty_struct *tty)¶ get a tty reference
Parameters
struct tty_struct *ttytty device
Return a new reference to a tty object. The caller must hold sufficient locks/counts to ensure that their existing reference cannot go away
-
void
tty_kref_put(struct tty_struct *tty)¶ release a tty kref
Parameters
struct tty_struct *ttytty device
Description
Release a reference to the tty device and if need be let the kref layer destruct the object for us.
Install¶
-
int
tty_standard_install(struct tty_driver *driver, struct tty_struct *tty)¶ usual tty->ops->install
Parameters
struct tty_driver *driverthe driver for the tty
struct tty_struct *ttythe tty
Description
If the driver overrides tty->ops->install, it still can call this function to perform the standard install operations.
Read & Write¶
-
int
tty_put_char(struct tty_struct *tty, unsigned char ch)¶ write one character to a tty
Parameters
struct tty_struct *ttytty
unsigned char chcharacter to write
Description
Write one byte to the tty using the provided tty->ops->put_char() method if present.
Note
the specific put_char operation in the driver layer may go away soon. Don’t call it directly, use this method
Return
the number of characters successfully output.
Start & Stop¶
-
void
stop_tty(struct tty_struct *tty)¶ propagate flow control
Parameters
struct tty_struct *ttytty to stop
Description
Perform flow control to the driver. May be called on an already stopped
device and will not re-call the tty_driver->stop() method.
This functionality is used by both the line disciplines for halting incoming
flow and by the driver. It may therefore be called from any context, may be
under the tty atomic_write_lock but not always.
- Locking:
flow.lock
-
void
start_tty(struct tty_struct *tty)¶ propagate flow control
Parameters
struct tty_struct *ttytty to start
Description
Start a tty that has been stopped if at all possible. If tty was previously
stopped and is now being started, the tty_driver->start() method is invoked
and the line discipline woken.
- Locking:
flow.lock
Wakeup¶
-
void
tty_wakeup(struct tty_struct *tty)¶ request more data
Parameters
struct tty_struct *ttyterminal
Description
Internal and external helper for wakeups of tty. This function informs the line discipline if present that the driver is ready to receive more output data.
Hangup¶
-
void
tty_hangup(struct tty_struct *tty)¶ trigger a hangup event
Parameters
struct tty_struct *ttytty to hangup
Description
A carrier loss (virtual or otherwise) has occurred on tty. Schedule a hangup sequence to run after this event.
-
void
tty_vhangup(struct tty_struct *tty)¶ process vhangup
Parameters
struct tty_struct *ttytty to hangup
Description
The user has asked via system call for the terminal to be hung up. We do this synchronously so that when the syscall returns the process is complete. That guarantee is necessary for security reasons.
-
int
tty_hung_up_p(struct file *filp)¶ was tty hung up
Parameters
struct file *filpfile pointer of tty
Return
true if the tty has been subject to a vhangup or a carrier loss
Misc¶
-
int
tty_do_resize(struct tty_struct *tty, struct winsize *ws)¶ resize event
Parameters
struct tty_struct *ttytty being resized
struct winsize *wsnew dimensions
Description
Update the termios variables and send the necessary signals to peform a terminal resize correctly.
TTY Struct Flags¶
These bits are used in the tty_struct.flags field.
So that interrupts won’t be able to mess up the queues,
copy_to_cooked must be atomic with respect to itself, as must
tty->write. Thus, you must use the inline functions set_bit() and
clear_bit() to make things atomic.
- TTY_THROTTLED
Driver input is throttled. The ldisc should call
tty_driver.unthrottle()in order to resume reception when it is ready to process more data (at threshold min).- TTY_IO_ERROR
If set, causes all subsequent userspace read/write calls on the tty to fail, returning -
EIO. (May be no ldisc too.)- TTY_OTHER_CLOSED
Device is a pty and the other side has closed.
- TTY_EXCLUSIVE
Exclusive open mode (a single opener).
- TTY_DO_WRITE_WAKEUP
If set, causes the driver to call the
tty_ldisc_ops.write_wakeup()method in order to resume transmission when it can accept more data to transmit.- TTY_LDISC_OPEN
Indicates that a line discipline is open. For debugging purposes only.
- TTY_PTY_LOCK
A flag private to pty code to implement
TIOCSPTLCK/TIOCGPTLCKlogic.- TTY_NO_WRITE_SPLIT
Prevent driver from splitting up writes into smaller chunks (preserve write boundaries to driver).
- TTY_HUPPED
The TTY was hung up. This is set post
tty_driver.hangup().- TTY_HUPPING
The TTY is in the process of hanging up to abort potential readers.
- TTY_LDISC_CHANGING
Line discipline for this TTY is being changed. I/O should not block when this is set. Use tty_io_nonblock() to check.
- TTY_LDISC_HALTED
Line discipline for this TTY was stopped. No work should be queued to this ldisc.
TTY Struct Reference¶
-
struct
tty_struct¶ state associated with a tty while open
Definition
struct tty_struct {
int magic;
struct kref kref;
struct device *dev;
struct tty_driver *driver;
const struct tty_operations *ops;
int index;
struct ld_semaphore ldisc_sem;
struct tty_ldisc *ldisc;
struct mutex atomic_write_lock;
struct mutex legacy_mutex;
struct mutex throttle_mutex;
struct rw_semaphore termios_rwsem;
struct mutex winsize_mutex;
struct ktermios termios, termios_locked;
char name[64];
unsigned long flags;
int count;
struct winsize winsize;
struct {
spinlock_t lock;
bool stopped;
bool tco_stopped;
unsigned long unused[0];
} flow;
struct {
spinlock_t lock;
struct pid *pgrp;
struct pid *session;
unsigned char pktstatus;
bool packet;
unsigned long unused[0];
} ctrl;
int hw_stopped;
unsigned int receive_room;
int flow_change;
struct tty_struct *link;
struct fasync_struct *fasync;
wait_queue_head_t write_wait;
wait_queue_head_t read_wait;
struct work_struct hangup_work;
void *disc_data;
void *driver_data;
spinlock_t files_lock;
struct list_head tty_files;
#define N_TTY_BUF_SIZE 4096;
int closing;
unsigned char *write_buf;
int write_cnt;
struct work_struct SAK_work;
struct tty_port *port;
};
Members
magicmagic value set early in alloc_tty_struct to
TTY_MAGIC, for debugging purposeskrefreference counting by
tty_kref_get()andtty_kref_put(), reaching zero frees the structuredevclass device or
NULL(e.g. ptys, serdev)driverstruct tty_driveroperating this ttyopsstruct tty_operationsof driver for this tty (open, close, etc.)indexindex of this tty (e.g. to construct name like tty12)
ldisc_semprotects line discipline changes (ldisc) – lock tty not pty
ldiscthe current line discipline for this tty (n_tty by default)
atomic_write_lockprotects against concurrent writers, i.e. locks write_cnt, write_buf and similar
legacy_mutexleftover from history (BKL -> BTM -> legacy_mutex), protecting several operations on this tty
throttle_mutexprotects against concurrent tty_throttle_safe() and tty_unthrottle_safe() (but not tty_unthrottle())
termios_rwsemprotects termios and termios_locked
winsize_mutexprotects winsize
termiostermios for the current tty, copied from/to driver.termios
termios_lockedlocked termios (by
TIOCGLCKTRMIOSandTIOCSLCKTRMIOSioctls)namename of the tty constructed by
tty_line_name()(e.g. ttyS3)flagsbitwise OR of
TTY_THROTTLED,TTY_IO_ERROR, …countcount of open processes, reaching zero cancels all the work for this tty and drops a kref too (but does not free this tty)
winsizesize of the terminal “window” (cf. winsize_mutex)
flowflow settings grouped together, see also flow.unused
flow.locklock for flow members
flow.stoppedtty stopped/started by
stop_tty()/start_tty()flow.tco_stoppedtty stopped/started by
TCOOFF/TCOONioctls (it has precedence over flow.stopped)flow.unusedalignment for Alpha, so that no members other than flow.* are modified by the same 64b word store. The flow’s __aligned is there for the very same reason.
ctrlcontrol settings grouped together, see also ctrl.unused
ctrl.locklock for ctrl members
ctrl.pgrpprocess group of this tty (setpgrp(2))
ctrl.sessionsession of this tty (setsid(2)). Writes are protected by both ctrl.lock and legacy_mutex, readers must use at least one of them.
ctrl.pktstatuspacket mode status (bitwise OR of
TIOCPKT_constants)ctrl.packetpacket mode enabled
ctrl.unusedalignment for Alpha, see flow.unused for explanation
hw_stoppednot controlled by the tty layer, under driver’s control for CTS handling
receive_roombytes permitted to feed to ldisc without any being lost
flow_changecontrols behavior of throttling, see tty_throttle_safe() and tty_unthrottle_safe()
linklink to another pty (master -> slave and vice versa)
fasyncstate for
O_ASYNC(forSIGIO); managed by fasync_helper()write_waitconcurrent writers are waiting in this queue until they are allowed to write
read_waitreaders wait for data in this queue
hangup_worknormally a work to perform a hangup (do_tty_hangup()); while freeing the tty, (re)used to
release_one_tty()disc_datapointer to ldisc’s private data (e.g. to
struct n_tty_data)driver_datapointer to driver’s private data (e.g.
struct uart_state)files_lockprotects tty_files list
tty_fileslist of (re)openers of this tty (i.e. linked
struct tty_file_private)closingwhen set during close, n_tty processes only START & STOP chars
write_buftemporary buffer used during
tty_write()to copy user data towrite_cntcount of bytes written in
tty_write()to write_bufSAK_workif the tty has a pending do_SAK, it is queued here
portpersistent storage for this device (i.e.
struct tty_port)
Description
All of the state associated with a tty while the tty is open. Persistent
storage for tty devices is referenced here as port and is documented in
struct tty_port.