STRUCT TTY_STRUCT(9)
π struct tty_struct(9) β Kernel API Manual π
okay so bestie, we're in struct tty_struct(9) territory, aka the Kernel API Manual page you did not know you needed but absolutely do. this is the whole vibe of a tty while it's open β every lock, every buffer, every little flag. it's giving backstage-pass-to-the-terminal. no cap.
β¨ SYNOPSIS β¨
like, the literal shape of it. don't touch, just vibe:
struct tty_struct {
struct kref kref;
int index;
struct device *dev;
struct tty_driver *driver;
struct tty_port *port;
const struct tty_operations *ops;
struct tty_ldisc *ldisc;
struct ld_semaphore ldisc_sem;
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;
unsigned int receive_room;
struct winsize winsize;
struct {
spinlock_t lock;
bool stopped;
bool tco_stopped;
} flow;
struct {
struct pid *pgrp;
struct pid *session;
spinlock_t lock;
unsigned char pktstatus;
bool packet;
} ctrl;
bool hw_stopped;
bool closing;
int flow_change;
struct tty_struct *link;
struct fasync_struct *fasync;
wait_queue_head_t write_wait;
wait_queue_head_t read_wait;
wait_queue_head_t break_wait;
struct work_struct hangup_work;
void *disc_data;
void *driver_data;
spinlock_t files_lock;
int write_cnt;
u8 *write_buf;
struct list_head tty_files;
struct work_struct SAK_work;
};
π Members π
grab a snack, we're going field by field. it's a lot. it's iconic. it's a journey.
krefβ reference counting handled bytty_kref_getandtty_kref_put; the way it works is when it hits zero the whole structure gets freed. πindexβ the index of this tty (think: so you can construct a name liketty12).devβ a class device, orNULL(like for ptys, serdev).driverβ thestruct tty_driverthat operates this tty.portβ the persistent storage for this device, akastruct tty_port.opsβ thestruct tty_operationsof the driver for this tty (open,close, etc.).ldiscβ the current line discipline for this tty (n_ttyby default).ldisc_semβ protects line discipline changes (ldisc) β and bestie, lock the tty, not the pty.atomic_write_lockβ protects against concurrent writers, i.e. it lockswrite_cnt,write_bufand similar.legacy_mutexβ a leftover from history (BKL -> BTM -> legacy_mutex), protecting several operations on this tty. yes it's old. yes it's still here. π«throttle_mutexβ protects against concurrenttty_throttle_safeandtty_unthrottle_safe(but nottty_unthrottle, mind you).termios_rwsemβ protectstermiosandtermios_locked.winsize_mutexβ protectswinsize.termiosβ the termios for the current tty, copied from/todriver.termios.termios_lockedβ locked termios (by theTIOCGLCKTRMIOSandTIOCSLCKTRMIOSioctls).nameβ the name of the tty, constructed bytty_line_name(e.g.ttyS3).flagsβ bitwise OR ofTTY_THROTTLED,TTY_IO_ERROR, ...countβ count of open processes; when it hits zero it cancels all the work for this tty and drops akreftoo (but it does not free this tty β important distinction, don't come for me).receive_roomβ bytes permitted to feed to ldisc without any being lost.winsizeβ the size of the terminal "window" (cf.winsize_mutex).flowβ flow settings, grouped together π«Άflow.lockβ lock forflowmembers.flow.stoppedβ tty stopped/started bystop_tty/start_tty.flow.tco_stoppedβ tty stopped/started byTCOOFF/TCOONioctls (and heads up: it has precedence overflow.stopped).ctrlβ control settings, also grouped together.ctrl.pgrpβ the process group of this tty (setpgrp(2)).ctrl.sessionβ the session of this tty (setsid(2)). Writes are protected by bothctrl.lockandlegacy_mutex, and readers must use at least one of them. no skipping, iykyk.ctrl.lockβ lock forctrlmembers.ctrl.pktstatusβ packet mode status (bitwise OR ofTIOCPKT_constants).ctrl.packetβ packet mode enabled.hw_stoppedβ not controlled by the tty layer; it's under the driver's control for CTS handling.closingβ when set during close,n_ttyprocesses onlySTART&STOPchars.flow_changeβ controls behavior of throttling, seetty_throttle_safeandtty_unthrottle_safe.linkβ link to another pty (master -> slave and vice versa) π¦fasyncβ state forO_ASYNC(forSIGIO); managed byfasync_helper.write_waitβ concurrent writers are waiting in this queue until they're allowed to write.read_waitβ readers wait for data in this queue.break_waitβ wait queue for timed breaks.hangup_workβ normally a work to perform a hangup (do_tty_hangup); while freeing the tty, it's (re)used torelease_one_tty.disc_dataβ pointer to ldisc's private data (e.g. tostruct n_tty_data).driver_dataβ pointer to driver's private data (e.g.struct uart_state).files_lockβ protects thetty_fileslist.write_cntβ count of bytes written intty_writetowrite_buf.write_bufβ temporary buffer used duringtty_writeto copy user data to.tty_filesβ list of (re)openers of this tty (i.e. linkedstruct tty_file_private).SAK_workβ if the tty has a pendingdo_SAK, it is queued here.
πΈ Description πΈ
literally all of the state associated with a tty while the tty is open. that's the whole bit. Persistent storage for tty devices is referenced here as port, and it's documented over in struct tty_port. go read that one next, bestie, it's the sequel. π
π SEE ALSO π
- Kernel file
./include/linux/tty.henumtty_struct_flags(9) tty_kref_get(9)tty_get_baud_rate(9)
and that's the page!! πβ¨ this little beauty lives under ./include/linux and was last touched in October 2026 β so like, yeah, mwah, slay, go read your ttys responsibly π
π«Ά
π¦ where this page comes from
- nixpkgs unstable: linux-manual 7.3.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms