drivers/tty/tty_io.c

Source file repositories/reference/linux-study-clean/drivers/tty/tty_io.c

File Facts

System
Linux kernel
Corpus path
drivers/tty/tty_io.c
Extension
.c
Size
91957 bytes
Lines
3673
Domain
Driver Families
Bucket
drivers/tty
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct file_operations tty_fops = {
	.read_iter	= tty_read,
	.write_iter	= tty_write,
	.splice_read	= copy_splice_read,
	.splice_write	= iter_file_splice_write,
	.poll		= tty_poll,
	.unlocked_ioctl	= tty_ioctl,
	.compat_ioctl	= tty_compat_ioctl,
	.open		= tty_open,
	.release	= tty_release,
	.fasync		= tty_fasync,
	.show_fdinfo	= tty_show_fdinfo,
};

static const struct file_operations console_fops = {
	.read_iter	= tty_read,
	.write_iter	= redirected_tty_write,
	.splice_read	= copy_splice_read,
	.splice_write	= iter_file_splice_write,
	.poll		= tty_poll,
	.unlocked_ioctl	= tty_ioctl,
	.compat_ioctl	= tty_compat_ioctl,
	.open		= tty_open,
	.release	= tty_release,
	.fasync		= tty_fasync,
};

static const struct file_operations hung_up_tty_fops = {
	.read_iter	= hung_up_tty_read,
	.write_iter	= hung_up_tty_write,
	.poll		= hung_up_tty_poll,
	.unlocked_ioctl	= hung_up_tty_ioctl,
	.compat_ioctl	= hung_up_tty_compat_ioctl,
	.release	= tty_release,
	.fasync		= hung_up_tty_fasync,
};

static DEFINE_SPINLOCK(redirect_lock);
static struct file *redirect;

/**
 * tty_wakeup - request more data
 * @tty: terminal
 *
 * 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.
 */
void tty_wakeup(struct tty_struct *tty)
{
	struct tty_ldisc *ld;

	if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) {
		ld = tty_ldisc_ref(tty);
		if (ld) {
			if (ld->ops->write_wakeup)
				ld->ops->write_wakeup(tty);
			tty_ldisc_deref(ld);
		}
	}
	wake_up_interruptible_poll(&tty->write_wait, EPOLLOUT);
}
EXPORT_SYMBOL_GPL(tty_wakeup);

/**
 * tty_release_redirect - Release a redirect on a pty if present
 * @tty: tty device
 *
 * This is available to the pty code so if the master closes, if the slave is a
 * redirect it can release the redirect.
 */
static struct file *tty_release_redirect(struct tty_struct *tty)
{
	guard(spinlock)(&redirect_lock);

	if (redirect && file_tty(redirect) == tty) {
		struct file *f = redirect;
		redirect = NULL;
		return f;
	}

	return NULL;
}

/**
 * __tty_hangup - actual handler for hangup events
 * @tty: tty device
 * @exit_session: if non-zero, signal all foreground group processes
 *
 * This can be called by a "kworker" kernel thread. That is process synchronous

Annotation

Implementation Notes