TTY Internals¶
Kopen¶
These functions serve for opening a TTY from the kernelspace:
- 
void tty_kclose(struct tty_struct *tty)¶
- closes tty opened by tty_kopen 
Parameters
- struct tty_struct *tty
- tty device 
Description
Performs the final steps to release and free a tty device. It is the same as
tty_release_struct() except that it also resets TTY_PORT_KOPENED flag on
tty->port.
- 
struct tty_struct *tty_kopen_exclusive(dev_t device)¶
- open a tty device for kernel 
Parameters
- dev_t device
- dev_t of device to open 
Description
Opens tty exclusively for kernel. Performs the driver lookup, makes sure it’s not already opened and performs the first-time tty initialization.
- Claims the global tty_mutexto serialize:
- concurrent first-time tty initialization 
- concurrent tty driver removal w/ lookup 
- concurrent tty removal from driver table 
 
Return
the locked initialized tty_struct
- open a tty device for shared in-kernel use 
Parameters
- dev_t device
- dev_t of device to open 
Description
Opens an already existing tty for in-kernel use. Compared to
tty_kopen_exclusive() above it doesn’t ensure to be the only user.
Locking: identical to tty_kopen() above.
Exported Internal Functions¶
- 
int tty_dev_name_to_number(const char *name, dev_t *number)¶
- return dev_t for device name 
Parameters
- const char *name
- user space name of device under /dev 
- dev_t *number
- pointer to dev_t that this function will populate 
Description
This function converts device names like ttyS0 or ttyUSB1 into dev_t like
(4, 64) or (188, 1). If no corresponding driver is registered then the
function returns -ENODEV.
- Locking: this acquires tty_mutex to protect the tty_drivers list from
- being modified while we are traversing it, and makes sure to release it before exiting. 
- 
void tty_release_struct(struct tty_struct *tty, int idx)¶
- release a tty struct 
Parameters
- struct tty_struct *tty
- tty device 
- int idx
- index of the tty 
Description
Performs the final steps to release and free a tty device. It is roughly the
reverse of tty_init_dev().
- 
int tty_get_icount(struct tty_struct *tty, struct serial_icounter_struct *icount)¶
- get tty statistics 
Parameters
- struct tty_struct *tty
- tty device 
- struct serial_icounter_struct *icount
- output parameter 
Description
Gets a copy of the tty’s icount statistics.
Locking: none (up to the driver)
Internal Functions¶
- 
void free_tty_struct(struct tty_struct *tty)¶
- free a disused tty 
Parameters
- struct tty_struct *tty
- tty struct to free 
Description
Free the write buffers, tty queue and tty memory itself.
Locking: none. Must be called after tty is definitely unused
Parameters
- struct file *file
- to free private_data of 
Description
This shall be used only for fail path handling when tty_add_file was not called yet.
- 
struct tty_driver *get_tty_driver(dev_t device, int *index)¶
- find device of a tty 
Parameters
- dev_t device
- device identifier 
- int *index
- returns the index of the tty 
Description
This routine returns a tty driver structure, given a device number and also passes back the index number.
Locking: caller must hold tty_mutex
- 
struct file *tty_release_redirect(struct tty_struct *tty)¶
- Release a redirect on a pty if present 
Parameters
- struct tty_struct *tty
- tty device 
Description
This is available to the pty code so if the master closes, if the slave is a redirect it can release the redirect.
- 
void __tty_hangup(struct tty_struct *tty, int exit_session)¶
- actual handler for hangup events 
Parameters
- struct tty_struct *tty
- tty device 
- int exit_session
- if non-zero, signal all foreground group processes 
Description
This can be called by a “kworker” kernel thread. That is process synchronous but doesn’t hold any locks, so we need to make sure we have the appropriate locks for what we’re doing.
The hangup event clears any pending redirections onto the hung up device. It ensures future writes will error and it does the needed line discipline hangup and signal delivery. The tty object itself remains intact.
- Locking:
- BTM 
 - redirect lock for undoing redirection 
- file list lock for manipulating list of ttys 
- tty_ldiscs_lock from called functions 
- termios_rwsem resetting termios data 
- tasklist_lock to walk task list for hangup event 
 - ->siglock to protect ->signal/->sighand 
 
- 
void tty_vhangup_self(void)¶
- process vhangup for own ctty 
Parameters
- void
- no arguments 
Description
Perform a vhangup on the current controlling tty
- 
void tty_vhangup_session(struct tty_struct *tty)¶
- hangup session leader exit 
Parameters
- struct tty_struct *tty
- tty to hangup 
Description
The session leader is exiting and hanging up its controlling terminal.
Every process in the foreground process group is signalled SIGHUP.
We do this synchronously so that when the syscall returns the process is complete. That guarantee is necessary for security reasons.
- 
ssize_t tty_read(struct kiocb *iocb, struct iov_iter *to)¶
- read method for tty device files 
Parameters
- struct kiocb *iocb
- kernel I/O control block 
- struct iov_iter *to
- destination for the data read 
Description
Perform the read system call function on this terminal device. Checks for hung up devices before calling the line discipline method.
- Locking:
- Locks the line discipline internally while needed. Multiple read calls may be outstanding in parallel. 
- 
void tty_write_message(struct tty_struct *tty, char *msg)¶
- write a message to a certain tty, not just the console. 
Parameters
- struct tty_struct *tty
- the destination tty_struct 
- char *msg
- the message to write 
Description
This is used for messages that need to be redirected to a specific tty. We don’t put it into the syslog queue right now maybe in the future if really needed.
We must still hold the BTM and test the CLOSING flag for the moment.
This function is DEPRECATED, do not use in new code.
- 
ssize_t tty_write(struct kiocb *iocb, struct iov_iter *from)¶
- write method for tty device file 
Parameters
- struct kiocb *iocb
- kernel I/O control block 
- struct iov_iter *from
- iov_iter with data to write 
Description
Write data to a tty device via the line discipline.
- Locking:
- Locks the line discipline as required Writes to the tty driver are serialized by the atomic_write_lock and are then processed in chunks to the device. The line discipline write method will not be invoked in parallel for each device. 
- 
int tty_send_xchar(struct tty_struct *tty, u8 ch)¶
- send priority character 
Parameters
- struct tty_struct *tty
- the tty to send to 
- u8 ch
- xchar to send 
Description
Send a high priority character to the tty even if stopped.
Locking: none for xchar method, write ordering for write method.
- 
void pty_line_name(struct tty_driver *driver, int index, char *p)¶
- generate name for a pty 
Parameters
- struct tty_driver *driver
- the tty driver in use 
- int index
- the minor number 
- char *p
- output buffer of at least 6 bytes 
Description
Generate a name from a driver reference and write it to the output buffer p.
Locking: None
- 
ssize_t tty_line_name(struct tty_driver *driver, int index, char *p)¶
- generate name for a tty 
Parameters
- struct tty_driver *driver
- the tty driver in use 
- int index
- the minor number 
- char *p
- output buffer of at least 7 bytes 
Description
Generate a name from a driver reference and write it to the output buffer p.
Locking: None
- 
struct tty_struct *tty_driver_lookup_tty(struct tty_driver *driver, struct file *file, int idx)¶
- find an existing tty, if any 
Parameters
- struct tty_driver *driver
- the driver for the tty 
- struct file *file
- file object 
- int idx
- the minor number 
Return
the tty, if found. If not found, return NULL or ERR_PTR() if the
driver lookup() method returns an error.
Description
Locking: tty_mutex must be held. If the tty is found, bump the tty kref.
- 
int tty_driver_install_tty(struct tty_driver *driver, struct tty_struct *tty)¶
- install a tty entry in the driver 
Parameters
- struct tty_driver *driver
- the driver for the tty 
- struct tty_struct *tty
- the tty 
Description
Install a tty object into the driver tables. The tty->index field will be set by the time this is called. This method is responsible for ensuring any need additional structures are allocated and configured.
Locking: tty_mutex for now
- 
void tty_driver_remove_tty(struct tty_driver *driver, struct tty_struct *tty)¶
- remove a tty from the driver tables 
Parameters
- struct tty_driver *driver
- the driver for the tty 
- struct tty_struct *tty
- tty to remove 
Description
Remove a tty object from the driver tables. The tty->index field will be set by the time this is called.
Locking: tty_mutex for now
- 
int tty_reopen(struct tty_struct *tty)¶
- fast re-open of an open tty 
Parameters
- struct tty_struct *tty
- the tty to open 
Description
Re-opens on master ptys are not allowed and return -EIO.
Locking: Caller must hold tty_lock
Return
0 on success, -errno on error.
- 
struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx)¶
- initialise a tty device 
Parameters
- struct tty_driver *driver
- tty driver we are opening a device on 
- int idx
- device index 
Description
Prepare a tty device. This may not be a “new” clean device but could also be an active device. The pty drivers require special handling because of this.
- Locking:
- The function is called under the tty_mutex, which protects us from the tty struct or driver itself going away. 
On exit the tty device has the line discipline attached and a reference count of 1. If a pair was created for pty/tty use and the other was a pty master then it too has a reference count of 1.
WSH 06/09/97: Rewritten to remove races and properly clean up after a failed open. The new code protects the open with a mutex, so it’s really quite straightforward. The mutex locking can probably be relaxed for the (most common) case of reopening a tty.
Return
new tty structure
- 
void tty_flush_works(struct tty_struct *tty)¶
- flush all works of a tty/pty pair 
Parameters
- struct tty_struct *tty
- tty device to flush works for (or either end of a pty pair) 
Description
Sync flush all works belonging to tty (and the ‘other’ tty).
- 
void release_one_tty(struct work_struct *work)¶
- release tty structure memory 
Parameters
- struct work_struct *work
- work of tty we are obliterating 
Description
Releases memory associated with a tty structure, and clears out the driver table slots. This function is called when a device is no longer in use. It also gets called when setup of a device fails.
- Locking:
- takes the file list lock internally when working on the list of ttys that the driver keeps. 
This method gets called from a work queue so that the driver private cleanup ops can sleep (needed for USB at least)
- 
void release_tty(struct tty_struct *tty, int idx)¶
- release tty structure memory 
Parameters
- struct tty_struct *tty
- tty device release 
- int idx
- index of the tty device release 
Description
Release both tty and a possible linked partner (think pty pair), and decrement the refcount of the backing module.
- Locking:
- tty_mutex takes the file list lock internally when working on the list of ttys that the driver keeps. 
- 
int tty_release_checks(struct tty_struct *tty, int idx)¶
- check a tty before real release 
Parameters
- struct tty_struct *tty
- tty to check 
- int idx
- index of the tty 
Description
Performs some paranoid checking before true release of the tty. This is a
no-op unless TTY_PARANOIA_CHECK is defined.
Parameters
- struct inode *inode
- inode of tty 
- struct file *filp
- file pointer for handle to tty 
Description
Called the last time each file handle is closed that references this tty. There may however be several such references.
- Locking:
- Takes BKL. See tty_release_dev(). 
Even releasing the tty structures is a tricky business. We have to be very careful that the structures are all released at the same time, as interrupts might otherwise get the wrong pointers.
WSH 09/09/97: rewritten to avoid some nasty race conditions that could lead to double frees or releasing memory still in use.
- 
struct tty_struct *tty_open_current_tty(dev_t device, struct file *filp)¶
- get locked tty of current task 
Parameters
- dev_t device
- device number 
- struct file *filp
- file pointer to tty 
Return
locked tty of the current task iff device is /dev/tty
Description
Performs a re-open of the current task’s controlling tty.
We cannot return driver and index like for the other nodes because devpts will not work then. It expects inodes to be from devpts FS.
- 
struct tty_driver *tty_lookup_driver(dev_t device, struct file *filp, int *index)¶
- lookup a tty driver for a given device file 
Parameters
- dev_t device
- device number 
- struct file *filp
- file pointer to tty 
- int *index
- index for the device in the return driver 
Description
If returned value is not erroneous, the caller is responsible to decrement
the refcount by tty_driver_kref_put().
Locking: tty_mutex protects get_tty_driver()
Return
driver for this inode (with increased refcount)
- 
struct tty_struct *tty_open_by_driver(dev_t device, struct file *filp)¶
- open a tty device 
Parameters
- dev_t device
- dev_t of device to open 
- struct file *filp
- file pointer to tty 
Description
Performs the driver lookup, checks for a reopen, or otherwise performs the first-time tty initialization.
- Claims the global tty_mutex to serialize:
- concurrent first-time tty initialization 
- concurrent tty driver removal w/ lookup 
- concurrent tty removal from driver table 
 
Return
the locked initialized or re-opened tty_struct
Parameters
- struct inode *inode
- inode of device file 
- struct file *filp
- file pointer to tty 
Description
tty_open() and tty_release() keep up the tty count that contains the number
of opens done on a tty. We cannot use the inode-count, as different inodes
might point to the same tty.
Open-counting is needed for pty masters, as well as for keeping track of serial lines: DTR is dropped when the last close happens. (This is not done solely through tty->count, now. - Ted 1/27/92)
The termios state of a pty is reset on the first open so that settings don’t persist across reuse.
- Locking:
- tty_mutexprotects tty,- tty_lookup_driver()and- tty_init_dev().
- tty->count should protect the rest. 
- ->siglock protects ->signal/->sighand 
 
Note
the tty_unlock/lock cases without a ref are only safe due to tty_mutex
Parameters
- struct file *filp
- file being polled 
- poll_table *wait
- poll wait structures to update 
Description
Call the line discipline polling method to obtain the poll status of the device.
Locking: locks called line discipline but ldisc poll method may be re-entered freely by other callers.
- 
int tiocsti(struct tty_struct *tty, u8 __user *p)¶
- fake input character 
Parameters
- struct tty_struct *tty
- tty to fake input into 
- u8 __user *p
- pointer to character 
Description
Fake input to a tty device. Does the necessary locking and input management.
FIXME: does not honour flow control ??
- Locking:
- Called functions take tty_ldiscs_lock 
- current->signal->tty check is safe without locks 
 
- 
int tiocgwinsz(struct tty_struct *tty, struct winsize __user *arg)¶
- implement window query ioctl 
Parameters
- struct tty_struct *tty
- tty 
- struct winsize __user *arg
- user buffer for result 
Description
Copies the kernel idea of the window size into the user buffer.
Locking: tty->winsize_mutex is taken to ensure the winsize data is consistent.
- 
int tiocswinsz(struct tty_struct *tty, struct winsize __user *arg)¶
- implement window size set ioctl 
Parameters
- struct tty_struct *tty
- tty side of tty 
- struct winsize __user *arg
- user buffer for result 
Description
Copies the user idea of the window size to the kernel. Traditionally this is just advisory information but for the Linux console it actually has driver level meaning and triggers a VC resize.
- Locking:
- Driver dependent. The default do_resize method takes the tty termios mutex and ctrl.lock. The console takes its own lock then calls into the default method. 
Parameters
- struct file *file
- the file to become console 
Description
Allow the administrator to move the redirected console device.
Locking: uses redirect_lock to guard the redirect information
- 
int tiocsetd(struct tty_struct *tty, int __user *p)¶
- set line discipline 
Parameters
- struct tty_struct *tty
- tty device 
- int __user *p
- pointer to user data 
Description
Set the line discipline according to user request.
Locking: see tty_set_ldisc(), this function is just a helper
- 
int tiocgetd(struct tty_struct *tty, int __user *p)¶
- get line discipline 
Parameters
- struct tty_struct *tty
- tty device 
- int __user *p
- pointer to user data 
Description
Retrieves the line discipline id directly from the ldisc.
Locking: waits for ldisc reference (in case the line discipline is changing or the tty is being hungup)
- 
int send_break(struct tty_struct *tty, unsigned int duration)¶
- performed time break 
Parameters
- struct tty_struct *tty
- device to break on 
- unsigned int duration
- timeout in mS 
Description
Perform a timed break on hardware that lacks its own driver level timed break functionality.
- Locking:
- tty->atomic_write_lock serializes 
- 
int tty_tiocmget(struct tty_struct *tty, int __user *p)¶
- get modem status 
Parameters
- struct tty_struct *tty
- tty device 
- int __user *p
- pointer to result 
Description
Obtain the modem status bits from the tty driver if the feature is
supported. Return -ENOTTY if it is not available.
Locking: none (up to the driver)
- 
int tty_tiocmset(struct tty_struct *tty, unsigned int cmd, unsigned __user *p)¶
- set modem status 
Parameters
- struct tty_struct *tty
- tty device 
- unsigned int cmd
- command - clear bits, set bits or set all 
- unsigned __user *p
- pointer to desired bits 
Description
Set the modem status bits from the tty driver if the feature
is supported. Return -ENOTTY if it is not available.
Locking: none (up to the driver)
- 
struct tty_struct *alloc_tty_struct(struct tty_driver *driver, int idx)¶
- allocate a new tty 
Parameters
- struct tty_driver *driver
- driver which will handle the returned tty 
- int idx
- minor of the tty 
Description
This subroutine allocates and initializes a tty structure.
Locking: none - tty in question is not exposed at this point