⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tty_ioctl.c

📁 LINUX1.0内核源代码,学习LINUX编程的一定要看。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  linux/kernel/drivers/char/tty_ioctl.c * *  Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds * * Modified by Fred N. van Kempen, 01/29/93, to add line disciplines * which can be dynamically activated and de-activated by the line * discipline handling modules (like SLIP). */#include <linux/types.h>#include <linux/termios.h>#include <linux/errno.h>#include <linux/sched.h>#include <linux/config.h>#include <linux/kernel.h>#include <linux/major.h>#include <linux/tty.h>#include <linux/fcntl.h>#include <linux/string.h>#include <asm/io.h>#include <asm/bitops.h>#include <asm/segment.h>#include <asm/system.h>#undef	DEBUG#ifdef DEBUG# define	PRINTK(x)	printk (x)#else# define	PRINTK(x)	/**/#endifextern int session_of_pgrp(int pgrp);extern int do_screendump(int arg);extern int kill_pg(int pgrp, int sig, int priv);#ifdef CONFIG_SELECTIONextern int set_selection(const int arg);extern int paste_selection(struct tty_struct *tty);#endif /* CONFIG_SELECTION */static int tty_set_ldisc(struct tty_struct *tty, int ldisc);void flush_input(struct tty_struct * tty){	cli();	tty->read_q.head = tty->read_q.tail = 0;	tty->secondary.head = tty->secondary.tail = 0;	tty->canon_head = tty->canon_data = tty->erasing = 0;	memset(&tty->readq_flags, 0, sizeof tty->readq_flags);	memset(&tty->secondary_flags, 0, sizeof tty->secondary_flags);	sti();	if (!tty->link)		return;	/* No cli() since ptys don't use interrupts. */	tty->link->write_q.head = tty->link->write_q.tail = 0;	wake_up_interruptible(&tty->link->write_q.proc_list);	if (tty->link->packet) {		tty->ctrl_status |= TIOCPKT_FLUSHREAD;		wake_up_interruptible(&tty->link->secondary.proc_list);	}}void flush_output(struct tty_struct * tty){	cli();	tty->write_q.head = tty->write_q.tail = 0;	sti();	wake_up_interruptible(&tty->write_q.proc_list);	if (!tty->link)		return;	/* No cli() since ptys don't use interrupts. */	tty->link->read_q.head = tty->link->read_q.tail = 0;	tty->link->secondary.head = tty->link->secondary.tail = 0;	tty->link->canon_head = tty->link->canon_data = tty->link->erasing = 0;	memset(&tty->link->readq_flags, 0, sizeof tty->readq_flags);	memset(&tty->link->secondary_flags, 0, sizeof tty->secondary_flags);	if (tty->link->packet) {		tty->ctrl_status |= TIOCPKT_FLUSHWRITE;		wake_up_interruptible(&tty->link->secondary.proc_list);	}}void wait_until_sent(struct tty_struct * tty, int timeout){	struct wait_queue wait = { current, NULL };	TTY_WRITE_FLUSH(tty);	if (EMPTY(&tty->write_q))		return;	add_wait_queue(&tty->write_q.proc_list, &wait);	current->counter = 0;	/* make us low-priority */	if (timeout)		current->timeout = timeout + jiffies;	else		current->timeout = (unsigned) -1;	do {		current->state = TASK_INTERRUPTIBLE;		if (current->signal & ~current->blocked)			break;		TTY_WRITE_FLUSH(tty);		if (EMPTY(&tty->write_q))			break;		schedule();	} while (current->timeout);	current->state = TASK_RUNNING;	remove_wait_queue(&tty->write_q.proc_list, &wait);}static int do_get_ps_info(int arg){	struct tstruct {		int flag;		int present[NR_TASKS];		struct task_struct tasks[NR_TASKS];	};	struct tstruct *ts = (struct tstruct *)arg;	struct task_struct **p;	char *c, *d;	int i, n = 0;		i = verify_area(VERIFY_WRITE, (void *)arg, sizeof(struct tstruct));	if (i)		return i;	for (p = &FIRST_TASK ; p <= &LAST_TASK ; p++, n++)		if (*p)		{			c = (char *)(*p);			d = (char *)(ts->tasks+n);			for (i=0 ; i<sizeof(struct task_struct) ; i++)				put_fs_byte(*c++, d++);			put_fs_long(1, (unsigned long *)(ts->present+n));		}		else				put_fs_long(0, (unsigned long *)(ts->present+n));	return(0);			}static void unset_locked_termios(struct termios *termios,				 struct termios *old,				 struct termios *locked){	int	i;	#define NOSET_MASK(x,y,z) (x = ((x) & ~(z)) | ((y) & (z)))	if (!locked) {		printk("Warning?!? termios_locked is NULL.\n");		return;	}	NOSET_MASK(termios->c_iflag, old->c_iflag, locked->c_iflag);	NOSET_MASK(termios->c_oflag, old->c_oflag, locked->c_oflag);	NOSET_MASK(termios->c_cflag, old->c_cflag, locked->c_cflag);	NOSET_MASK(termios->c_lflag, old->c_lflag, locked->c_lflag);	termios->c_line = locked->c_line ? old->c_line : termios->c_line;	for (i=0; i < NCCS; i++)		termios->c_cc[i] = locked->c_cc[i] ?			old->c_cc[i] : termios->c_cc[i];}int check_change(struct tty_struct * tty, int channel){	/* If we try to set the state of terminal and we're not in the	   foreground, send a SIGTTOU.  If the signal is blocked or	   ignored, go ahead and perform the operation.  POSIX 7.2) */	if (current->tty != channel)		return 0;	if (tty->pgrp <= 0) {		printk("check_change: tty->pgrp <= 0!\n");		return 0;	}	if (current->pgrp == tty->pgrp)		return 0;	if (is_ignored(SIGTTOU))		return 0;	if (is_orphaned_pgrp(current->pgrp))		return -EIO;	(void) kill_pg(current->pgrp,SIGTTOU,1);	return -ERESTARTSYS;}static int set_termios_2(struct tty_struct * tty, struct termios * termios){	struct termios old_termios = *tty->termios;	int canon_change;	canon_change = (old_termios.c_lflag ^ termios->c_lflag) & ICANON;	cli();	*tty->termios = *termios;	if (canon_change) {		memset(&tty->secondary_flags, 0, sizeof tty->secondary_flags);		tty->canon_head = tty->secondary.tail;		tty->canon_data = 0;		tty->erasing = 0;	}	sti();	if (canon_change && !L_ICANON(tty) && !EMPTY(&tty->secondary))		/* Get characters left over from canonical mode. */		wake_up_interruptible(&tty->secondary.proc_list);	/* see if packet mode change of state */	if (tty->link && tty->link->packet) {		int old_flow = ((old_termios.c_iflag & IXON) &&				(old_termios.c_cc[VSTOP] == '\023') &&				(old_termios.c_cc[VSTART] == '\021'));		int new_flow = (I_IXON(tty) &&				STOP_CHAR(tty) == '\023' &&				START_CHAR(tty) == '\021');		if (old_flow != new_flow) {			tty->ctrl_status &= ~(TIOCPKT_DOSTOP | TIOCPKT_NOSTOP);			if (new_flow)				tty->ctrl_status |= TIOCPKT_DOSTOP;			else				tty->ctrl_status |= TIOCPKT_NOSTOP;			wake_up_interruptible(&tty->link->secondary.proc_list);		}	}	unset_locked_termios(tty->termios, &old_termios,			     termios_locked[tty->line]);	if (tty->set_termios)		(*tty->set_termios)(tty, &old_termios);	return 0;}static int set_termios(struct tty_struct * tty, struct termios * termios,		       int channel){	struct termios tmp_termios;	memcpy_fromfs(&tmp_termios, termios, sizeof (struct termios));	return set_termios_2(tty, &tmp_termios);}static int get_termio(struct tty_struct * tty, struct termio * termio){	int i;	struct termio tmp_termio;	i = verify_area(VERIFY_WRITE, termio, sizeof (struct termio));	if (i)		return i;	tmp_termio.c_iflag = tty->termios->c_iflag;	tmp_termio.c_oflag = tty->termios->c_oflag;	tmp_termio.c_cflag = tty->termios->c_cflag;	tmp_termio.c_lflag = tty->termios->c_lflag;	tmp_termio.c_line = tty->termios->c_line;	for(i=0 ; i < NCC ; i++)		tmp_termio.c_cc[i] = tty->termios->c_cc[i];	memcpy_tofs(termio, &tmp_termio, sizeof (struct termio));	return 0;}static int set_termio(struct tty_struct * tty, struct termio * termio,		      int channel){	struct termio tmp_termio;	struct termios tmp_termios;	tmp_termios = *tty->termios;	memcpy_fromfs(&tmp_termio, termio, sizeof (struct termio));#define SET_LOW_BITS(x,y)	((x) = (0xffff0000 & (x)) | (y))	SET_LOW_BITS(tmp_termios.c_iflag, tmp_termio.c_iflag);	SET_LOW_BITS(tmp_termios.c_oflag, tmp_termio.c_oflag);	SET_LOW_BITS(tmp_termios.c_cflag, tmp_termio.c_cflag);	SET_LOW_BITS(tmp_termios.c_lflag, tmp_termio.c_lflag);	memcpy(&tmp_termios.c_cc, &tmp_termio.c_cc, NCC);#undef SET_LOW_BITS	return set_termios_2(tty, &tmp_termios);}static int set_window_size(struct tty_struct * tty, struct winsize * ws){	struct winsize tmp_ws;	memcpy_fromfs(&tmp_ws, ws, sizeof (struct winsize));	if (memcmp(&tmp_ws, &tty->winsize, sizeof (struct winsize)) &&	    tty->pgrp > 0)		kill_pg(tty->pgrp, SIGWINCH, 1);	tty->winsize = tmp_ws;	return 0;}/* Set the discipline of a tty line. */static int tty_set_ldisc(struct tty_struct *tty, int ldisc){	if ((ldisc < N_TTY) || (ldisc >= NR_LDISCS) ||	    !(ldiscs[ldisc].flags & LDISC_FLAG_DEFINED))		return -EINVAL;	if (tty->disc == ldisc)		return 0;	/* We are already in the desired discipline */	/* Shutdown the current discipline. */	wait_until_sent(tty, 0);	flush_input(tty);	if (ldiscs[tty->disc].close)		ldiscs[tty->disc].close(tty);	/* Now set up the new line discipline. */	tty->disc = ldisc;	tty->termios->c_line = ldisc;	if (ldiscs[tty->disc].open)		return(ldiscs[tty->disc].open(tty));	else		return 0;}static unsigned long inq_canon(struct tty_struct * tty){	int nr, head, tail;	if (!tty->canon_data)		return 0;	head = tty->canon_head;	tail = tty->secondary.tail;	nr = (head - tail) & (TTY_BUF_SIZE-1);	/* Skip EOF-chars.. */	while (head != tail) {		if (test_bit(tail, &tty->secondary_flags) &&		    tty->secondary.buf[tail] == __DISABLED_CHAR)			nr--;		INC(tail);	}	return nr;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -