TTY Internals¶
Kopen¶
These functions serve for opening a TTY from the kernelspace:
- voidtty_kclose(structtty_struct*tty)¶
closes tty opened by tty_kopen
Parameters
structtty_struct*ttytty device
Description
Performs the final steps to release and free a tty device. It is the same astty_release_struct() except that it also resetsTTY_PORT_KOPENED flag ontty->port.
- structtty_struct*tty_kopen_exclusive(dev_tdevice)¶
open a tty device for kernel
Parameters
dev_tdevicedev_t of device to open
Description
Opens tty exclusively for kernel. Performs the driver lookup, makes sureit’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 initializedtty_struct
- structtty_struct*tty_kopen_shared(dev_tdevice)¶
open a tty device for shared in-kernel use
Parameters
dev_tdevicedev_t of device to open
Description
Opens an already existing tty for in-kernel use. Compared totty_kopen_exclusive() above it doesn’t ensure to be the only user.
Locking: identical totty_kopen() above.
Exported Internal Functions¶
- inttty_dev_name_to_number(constchar*name,dev_t*number)¶
return dev_t for device name
Parameters
constchar*nameuser space name of device under /dev
dev_t*numberpointer 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 thefunction returns -ENODEV.
- Locking: this acquires tty_mutex to protect the tty_drivers list from
being modified while we are traversing it, and makes sure torelease it before exiting.
- voidtty_release_struct(structtty_struct*tty,intidx)¶
release a tty struct
Parameters
structtty_struct*ttytty device
intidxindex of the tty
Description
Performs the final steps to release and free a tty device. It is roughly thereverse oftty_init_dev().
- inttty_get_icount(structtty_struct*tty,structserial_icounter_struct*icount)¶
get tty statistics
Parameters
structtty_struct*ttytty device
structserial_icounter_struct*icountoutput parameter
Description
Gets a copy of thetty’s icount statistics.
Locking: none (up to the driver)
Internal Functions¶
- voidfree_tty_struct(structtty_struct*tty)¶
free a disused tty
Parameters
structtty_struct*ttytty
structtofree
Description
Free the write buffers, tty queue and tty memory itself.
Locking: none. Must be called after tty is definitely unused
Parameters
structfile*fileto free private_data of
Description
This shall be used only for fail path handling when tty_add_file was notcalled yet.
- structtty_driver*get_tty_driver(dev_tdevice,int*index)¶
find device of a tty
Parameters
dev_tdevicedevice identifier
int*indexreturns the index of the tty
Description
This routine returns a tty driver structure, given a device number and alsopasses back the index number.
Locking: caller must hold tty_mutex
- structfile*tty_release_redirect(structtty_struct*tty)¶
Release a redirect on a pty if present
Parameters
structtty_struct*ttytty device
Description
This is available to the pty code so if the master closes, if the slave is aredirect it can release the redirect.
- void__tty_hangup(structtty_struct*tty,intexit_session)¶
actual handler for hangup events
Parameters
structtty_struct*ttytty device
intexit_sessionif non-zero, signal all foreground group processes
Description
This can be called by a “kworker” kernel thread. That is process synchronousbut doesn’t hold any locks, so we need to make sure we have the appropriatelocks for what we’re doing.
The hangup event clears any pending redirections onto the hung up device. Itensures future writes will error and it does the needed line disciplinehangup 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
- voidtty_vhangup_self(void)¶
process vhangup for own ctty
Parameters
voidno arguments
Description
Perform a vhangup on the current controlling tty
- voidtty_vhangup_session(structtty_struct*tty)¶
hangup session leader exit
Parameters
structtty_struct*ttytty to hangup
Description
The session leader is exiting and hanging up its controlling terminal.Every process in the foreground process group is signalledSIGHUP.
We do this synchronously so that when the syscall returns the process iscomplete. That guarantee is necessary for security reasons.
- ssize_ttty_read(structkiocb*iocb,structiov_iter*to)¶
read method for tty device files
Parameters
structkiocb*iocbkernel I/O control block
structiov_iter*todestination for the data read
Description
Perform the read system call function on this terminal device. Checksfor hung up devices before calling the line discipline method.
- Locking:
Locks the line discipline internally while needed. Multiple read callsmay be outstanding in parallel.
- voidtty_write_message(structtty_struct*tty,char*msg)¶
write a message to a certain tty, not just the console.
Parameters
structtty_struct*ttythe destination tty_struct
char*msgthe message to write
Description
This is used for messages that need to be redirected to a specific tty. Wedon’t put it into the syslog queue right now maybe in the future if reallyneeded.
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_ttty_write(structkiocb*iocb,structiov_iter*from)¶
write method for tty device file
Parameters
structkiocb*iocbkernel I/O control block
structiov_iter*fromiov_iter with data to write
Description
Write data to a tty device via the line discipline.
- Locking:
Locks the line discipline as requiredWrites to the tty driver are serialized by the atomic_write_lockand are then processed in chunks to the device. The linediscipline write method will not be invoked in parallel foreach device.
- inttty_send_xchar(structtty_struct*tty,u8ch)¶
send priority character
Parameters
structtty_struct*ttythe tty to send to
u8chxchar to send
Description
Send a high priority character to the tty even if stopped.
Locking: none for xchar method, write ordering for write method.
- voidpty_line_name(structtty_driver*driver,intindex,char*p)¶
generate name for a pty
Parameters
structtty_driver*driverthe tty driver in use
intindexthe minor number
char*poutput buffer of at least 6 bytes
Description
Generate a name from adriver reference and write it to the output bufferp.
Locking: None
- ssize_ttty_line_name(structtty_driver*driver,intindex,char*p)¶
generate name for a tty
Parameters
structtty_driver*driverthe tty driver in use
intindexthe minor number
char*poutput buffer of at least 7 bytes
Description
Generate a name from adriver reference and write it to the output bufferp.
Locking: None
- structtty_struct*tty_driver_lookup_tty(structtty_driver*driver,structfile*file,intidx)¶
find an existing tty, if any
Parameters
structtty_driver*driverthe driver for the tty
structfile*filefile object
intidxthe minor number
Return
the tty, if found. If not found, returnNULL orERR_PTR() if thedriverlookup() method returns an error.
Description
Locking: tty_mutex must be held. If the tty is found, bump the tty kref.
- inttty_driver_install_tty(structtty_driver*driver,structtty_struct*tty)¶
install a tty entry in the driver
Parameters
structtty_driver*driverthe driver for the tty
structtty_struct*ttythe tty
Description
Install a tty object into the driver tables. Thetty->index field will beset by the time this is called. This method is responsible for ensuring anyneed additional structures are allocated and configured.
Locking: tty_mutex for now
- voidtty_driver_remove_tty(structtty_driver*driver,structtty_struct*tty)¶
remove a tty from the driver tables
Parameters
structtty_driver*driverthe driver for the tty
structtty_struct*ttytty to remove
Description
Remove a tty object from the driver tables. The tty->index field will be setby the time this is called.
Locking: tty_mutex for now
- inttty_reopen(structtty_struct*tty)¶
fast re-open of an open tty
Parameters
structtty_struct*ttythe 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.
- structtty_struct*tty_init_dev(structtty_driver*driver,intidx)¶
initialise a tty device
Parameters
structtty_driver*drivertty driver we are opening a device on
intidxdevice index
Description
Prepare a tty device. This may not be a “new” clean device but could also bean active device. The pty drivers require special handling because of this.
- Locking:
The function is called under the tty_mutex, which protects us from thetty
structordriver itself going away.
On exit the tty device has the line discipline attached and a referencecount of 1. If a pair was created for pty/tty use and the other was a ptymaster then it too has a reference count of 1.
WSH 06/09/97: Rewritten to remove races and properly clean up after a failedopen. The new code protects the open with a mutex, so it’s really quitestraightforward. The mutex locking can probably be relaxed for the (mostcommon) case of reopening a tty.
Return
new tty structure
- voidtty_flush_works(structtty_struct*tty)¶
flush all works of a tty/pty pair
Parameters
structtty_struct*ttytty device to flush works for (or either end of a pty pair)
Description
Sync flush all works belonging totty (and the ‘other’ tty).
- voidrelease_one_tty(structwork_struct*work)¶
release tty structure memory
Parameters
structwork_struct*workwork of tty we are obliterating
Description
Releases memory associated with a tty structure, and clears out thedriver table slots. This function is called when a device is no longerin use. It also gets called when setup of a device fails.
- Locking:
takes the file list lock internally when working on the list of ttysthat the driver keeps.
This method gets called from a work queue so that the driver privatecleanup ops can sleep (needed for USB at least)
- voidrelease_tty(structtty_struct*tty,intidx)¶
release tty structure memory
Parameters
structtty_struct*ttytty device release
intidxindex of the tty device release
Description
Release bothtty and a possible linked partner (think pty pair),and decrement the refcount of the backing module.
- Locking:
tty_mutextakes the file list lock internally when working on the list of ttysthat the driver keeps.
- inttty_release_checks(structtty_struct*tty,intidx)¶
check a tty before real release
Parameters
structtty_struct*ttytty to check
intidxindex of the tty
Description
Performs some paranoid checking before true release of thetty. This is ano-op unlessTTY_PARANOIA_CHECK is defined.
Parameters
structinode*inodeinode of tty
structfile*filpfile 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 verycareful that the structures are all released at the same time, as interruptsmight otherwise get the wrong pointers.
WSH 09/09/97: rewritten to avoid some nasty race conditions that couldlead to double frees or releasing memory still in use.
- structtty_struct*tty_open_current_tty(dev_tdevice,structfile*filp)¶
get locked tty of current task
Parameters
dev_tdevicedevice number
structfile*filpfile pointer to tty
Return
locked tty of the current task iffdevice 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 devptswill not work then. It expects inodes to be from devpts FS.
- structtty_driver*tty_lookup_driver(dev_tdevice,structfile*filp,int*index)¶
lookup a tty driver for a given device file
Parameters
dev_tdevicedevice number
structfile*filpfile pointer to tty
int*indexindex for the device in thereturn driver
Description
If returned value is not erroneous, the caller is responsible to decrementthe refcount bytty_driver_kref_put().
Locking:tty_mutex protectsget_tty_driver()
Return
driver for this inode (with increased refcount)
- structtty_struct*tty_open_by_driver(dev_tdevice,structfile*filp)¶
open a tty device
Parameters
dev_tdevicedev_t of device to open
structfile*filpfile pointer to tty
Description
Performs the driver lookup, checks for a reopen, or otherwise performs thefirst-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-openedtty_struct
Parameters
structinode*inodeinode of device file
structfile*filpfile pointer to tty
Description
tty_open() andtty_release() keep up the tty count that contains the numberof opens done on a tty. We cannot use the inode-count, as different inodesmight point to the same tty.
Open-counting is needed for pty masters, as well as for keeping track ofserial 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’tpersist across reuse.
- Locking:
tty_mutexprotects tty,tty_lookup_driver()andtty_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 totty_mutex
Parameters
structfile*filpfile being polled
poll_table*waitpoll wait structures to update
Description
Call the line discipline polling method to obtain the poll status of thedevice.
Locking: locks called line discipline but ldisc poll method may bere-entered freely by other callers.
- inttiocsti(structtty_struct*tty,u8__user*p)¶
fake input character
Parameters
structtty_struct*ttytty to fake input into
u8__user*ppointer 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
- inttiocgwinsz(structtty_struct*tty,structwinsize__user*arg)¶
implement window query ioctl
Parameters
structtty_struct*ttytty
structwinsize__user*arguser 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 isconsistent.
- inttiocswinsz(structtty_struct*tty,structwinsize__user*arg)¶
implement window size set ioctl
Parameters
structtty_struct*ttytty side of tty
structwinsize__user*arguser buffer for result
Description
Copies the user idea of the window size to the kernel. Traditionally this isjust advisory information but for the Linux console it actually has driverlevel meaning and triggers a VC resize.
- Locking:
Driver dependent. The default do_resize method takes the tty termiosmutex and ctrl.lock. The console takes its own lock then calls into thedefault method.
Parameters
structfile*filethe file to become console
Description
Allow the administrator to move the redirected console device.
Locking: uses redirect_lock to guard the redirect information
- inttiocsetd(structtty_struct*tty,int__user*p)¶
set line discipline
Parameters
structtty_struct*ttytty device
int__user*ppointer to user data
Description
Set the line discipline according to user request.
Locking: seetty_set_ldisc(), this function is just a helper
- inttiocgetd(structtty_struct*tty,int__user*p)¶
get line discipline
Parameters
structtty_struct*ttytty device
int__user*ppointer to user data
Description
Retrieves the line discipline id directly from the ldisc.
Locking: waits for ldisc reference (in case the line discipline is changingor thetty is being hungup)
- intsend_break(structtty_struct*tty,unsignedintduration)¶
performed time break
Parameters
structtty_struct*ttydevice to break on
unsignedintdurationtimeout in mS
Description
Perform a timed break on hardware that lacks its own driver level timedbreak functionality.
- Locking:
tty->atomic_write_lock serializes
- inttty_tiocmget(structtty_struct*tty,int__user*p)¶
get modem status
Parameters
structtty_struct*ttytty device
int__user*ppointer to result
Description
Obtain the modem status bits from the tty driver if the feature issupported. Return -ENOTTY if it is not available.
Locking: none (up to the driver)
- inttty_tiocmset(structtty_struct*tty,unsignedintcmd,unsigned__user*p)¶
set modem status
Parameters
structtty_struct*ttytty device
unsignedintcmdcommand - clear bits, set bits or set all
unsigned__user*ppointer to desired bits
Description
Set the modem status bits from the tty driver if the featureis supported. Return -ENOTTY if it is not available.
Locking: none (up to the driver)
- structtty_struct*alloc_tty_struct(structtty_driver*driver,intidx)¶
allocate a new tty
Parameters
structtty_driver*driverdriver which will handle the returned tty
intidxminor of the tty
Description
This subroutine allocates and initializes a tty structure.
Locking: none -tty in question is not exposed at this point