tty.c

来自「minix操作系统最新版本(3.1.1)的源代码」· C语言 代码 · 共 1,994 行 · 第 1/4 页

C
1,994
字号
}/*===========================================================================* *				tty_init				     * *===========================================================================*/PRIVATE void tty_init(){/* Initialize tty structure and call device initialization routines. */  register tty_t *tp;  int s;  struct sigaction sa;  /* Initialize the terminal lines. */  for (tp = FIRST_TTY,s=0; tp < END_TTY; tp++,s++) {  	tp->tty_index = s;  	tmr_inittimer(&tp->tty_tmr);  	tp->tty_intail = tp->tty_inhead = tp->tty_inbuf;  	tp->tty_min = 1;  	tp->tty_termios = termios_defaults;  	tp->tty_icancel = tp->tty_ocancel = tp->tty_ioctl = tp->tty_close =								tty_devnop;  	if (tp < tty_addr(NR_CONS)) {		scr_init(tp);  		tp->tty_minor = CONS_MINOR + s;  	} else  	if (tp < tty_addr(NR_CONS+NR_RS_LINES)) {		rs_init(tp);  		tp->tty_minor = RS232_MINOR + s-NR_CONS;  	} else {		pty_init(tp);		tp->tty_minor = s - (NR_CONS+NR_RS_LINES) + TTYPX_MINOR;  	}  }#if DEAD_CODE  /* Install signal handlers. Ask PM to transform signal into message. */  sa.sa_handler = SIG_MESS;  sigemptyset(&sa.sa_mask);  sa.sa_flags = 0;  if (sigaction(SIGTERM,&sa,NULL)<0) panic("TTY","sigaction failed", errno);  if (sigaction(SIGKMESS,&sa,NULL)<0) panic("TTY","sigaction failed", errno);  if (sigaction(SIGKSTOP,&sa,NULL)<0) panic("TTY","sigaction failed", errno);#endif}/*===========================================================================* *				tty_timed_out				     * *===========================================================================*/PRIVATE void tty_timed_out(timer_t *tp){/* This timer has expired. Set the events flag, to force processing. */  tty_t *tty_ptr;  tty_ptr = &tty_table[tmr_arg(tp)->ta_int];  tty_ptr->tty_min = 0;			/* force read to succeed */  tty_ptr->tty_events = 1;		}/*===========================================================================* *				expire_timers			    	     * *===========================================================================*/PRIVATE void expire_timers(void){/* A synchronous alarm message was received. Check if there are any expired  * timers. Possibly set the event flag and reschedule another alarm.   */  clock_t now;				/* current time */  int s;  /* Get the current time to compare the timers against. */  if ((s=getuptime(&now)) != OK) 	panic("TTY","Couldn't get uptime from clock.", s);  /* Scan the queue of timers for expired timers. This dispatch the watchdog   * functions of expired timers. Possibly a new alarm call must be scheduled.   */  tmrs_exptimers(&tty_timers, now, NULL);  if (tty_timers == NULL) tty_next_timeout = TMR_NEVER;  else {  					  /* set new sync alarm */  	tty_next_timeout = tty_timers->tmr_exp_time;  	if ((s=sys_setalarm(tty_next_timeout, 1)) != OK) 		panic("TTY","Couldn't set synchronous alarm.", s);  }}/*===========================================================================* *				settimer				     * *===========================================================================*/PRIVATE void settimer(tty_ptr, enable)tty_t *tty_ptr;			/* line to set or unset a timer on */int enable;			/* set timer if true, otherwise unset */{  clock_t now;				/* current time */  clock_t exp_time;  int s;  /* Get the current time to calculate the timeout time. */  if ((s=getuptime(&now)) != OK) 	panic("TTY","Couldn't get uptime from clock.", s);  if (enable) {  	exp_time = now + tty_ptr->tty_termios.c_cc[VTIME] * (HZ/10); 	/* Set a new timer for enabling the TTY events flags. */ 	tmrs_settimer(&tty_timers, &tty_ptr->tty_tmr,  		exp_time, tty_timed_out, NULL);    } else {  	/* Remove the timer from the active and expired lists. */  	tmrs_clrtimer(&tty_timers, &tty_ptr->tty_tmr, NULL);  }    /* Now check if a new alarm must be scheduled. This happens when the front   * of the timers queue was disabled or reinserted at another position, or   * when a new timer was added to the front.   */  if (tty_timers == NULL) tty_next_timeout = TMR_NEVER;  else if (tty_timers->tmr_exp_time != tty_next_timeout) {   	tty_next_timeout = tty_timers->tmr_exp_time;  	if ((s=sys_setalarm(tty_next_timeout, 1)) != OK) 		panic("TTY","Couldn't set synchronous alarm.", s);  }}/*===========================================================================* *				tty_devnop				     * *===========================================================================*/PUBLIC int tty_devnop(tp, try)tty_t *tp;int try;{  /* Some functions need not be implemented at the device level. */}/*===========================================================================* *				do_select				     * *===========================================================================*/PRIVATE void do_select(tp, m_ptr)register tty_t *tp;		/* pointer to tty struct */register message *m_ptr;	/* pointer to message sent to the task */{	int ops, ready_ops = 0, watch;	ops = m_ptr->PROC_NR & (SEL_RD|SEL_WR|SEL_ERR);	watch = (m_ptr->PROC_NR & SEL_NOTIFY) ? 1 : 0;	ready_ops = select_try(tp, ops);	if (!ready_ops && ops && watch) {		tp->tty_select_ops |= ops;		tp->tty_select_proc = m_ptr->m_source;	}        tty_reply(TASK_REPLY, m_ptr->m_source, m_ptr->PROC_NR, ready_ops);        return;}#if ENABLE_SRCCOMPAT || ENABLE_BINCOMPAT/*===========================================================================* *				compat_getp				     * *===========================================================================*/PRIVATE int compat_getp(tp, sg)tty_t *tp;struct sgttyb *sg;{/* Translate an old TIOCGETP to the termios equivalent. */  int flgs;  sg->sg_erase = tp->tty_termios.c_cc[VERASE];  sg->sg_kill = tp->tty_termios.c_cc[VKILL];  sg->sg_ospeed = tspd2sgspd(cfgetospeed(&tp->tty_termios));  sg->sg_ispeed = tspd2sgspd(cfgetispeed(&tp->tty_termios));  flgs = 0;  /* XTABS	- if OPOST and XTABS */  if ((tp->tty_termios.c_oflag & (OPOST|XTABS)) == (OPOST|XTABS))	flgs |= 0006000;  /* BITS5..BITS8  - map directly to CS5..CS8 */  flgs |= (tp->tty_termios.c_cflag & CSIZE) << (8-2);  /* EVENP	- if PARENB and not PARODD */  if ((tp->tty_termios.c_cflag & (PARENB|PARODD)) == PARENB)	flgs |= 0000200;  /* ODDP	- if PARENB and PARODD */  if ((tp->tty_termios.c_cflag & (PARENB|PARODD)) == (PARENB|PARODD))	flgs |= 0000100;  /* RAW	- if not ICANON and not ISIG */  if (!(tp->tty_termios.c_lflag & (ICANON|ISIG)))	flgs |= 0000040;  /* CRMOD	- if ICRNL */  if (tp->tty_termios.c_iflag & ICRNL)	flgs |= 0000020;  /* ECHO	- if ECHO */  if (tp->tty_termios.c_lflag & ECHO)	flgs |= 0000010;  /* CBREAK	- if not ICANON and ISIG */  if ((tp->tty_termios.c_lflag & (ICANON|ISIG)) == ISIG)	flgs |= 0000002;  sg->sg_flags = flgs;  return(OK);}/*===========================================================================* *				compat_getc				     * *===========================================================================*/PRIVATE int compat_getc(tp, tc)tty_t *tp;struct tchars *tc;{/* Translate an old TIOCGETC to the termios equivalent. */  tc->t_intrc = tp->tty_termios.c_cc[VINTR];  tc->t_quitc = tp->tty_termios.c_cc[VQUIT];  tc->t_startc = tp->tty_termios.c_cc[VSTART];  tc->t_stopc = tp->tty_termios.c_cc[VSTOP];  tc->t_brkc = tp->tty_termios.c_cc[VEOL];  tc->t_eofc = tp->tty_termios.c_cc[VEOF];  return(OK);}/*===========================================================================* *				compat_setp				     * *===========================================================================*/PRIVATE int compat_setp(tp, sg)tty_t *tp;struct sgttyb *sg;{/* Translate an old TIOCSETP to the termios equivalent. */  struct termios termios;  int flags;  termios = tp->tty_termios;  termios.c_cc[VERASE] = sg->sg_erase;  termios.c_cc[VKILL] = sg->sg_kill;  cfsetispeed(&termios, sgspd2tspd(sg->sg_ispeed & BYTE));  cfsetospeed(&termios, sgspd2tspd(sg->sg_ospeed & BYTE));  flags = sg->sg_flags;  /* Input flags */  /* BRKINT	- not changed */  /* ICRNL	- set if CRMOD is set and not RAW */  /*		  (CRMOD also controls output) */  termios.c_iflag &= ~ICRNL;  if ((flags & 0000020) && !(flags & 0000040))	termios.c_iflag |= ICRNL;  /* IGNBRK	- not changed */  /* IGNCR	- forced off (ignoring cr's is not supported) */  termios.c_iflag &= ~IGNCR;  /* IGNPAR	- not changed */  /* INLCR	- forced off (mapping nl's to cr's is not supported) */  termios.c_iflag &= ~INLCR;  /* INPCK	- not changed */  /* ISTRIP	- not changed */  /* IXOFF	- not changed */  /* IXON	- forced on if not RAW */  termios.c_iflag &= ~IXON;  if (!(flags & 0000040))	termios.c_iflag |= IXON;  /* PARMRK	- not changed */  /* Output flags */  /* OPOST	- forced on if not RAW */  termios.c_oflag &= ~OPOST;  if (!(flags & 0000040))	termios.c_oflag |= OPOST;  /* ONLCR	- forced on if CRMOD */  termios.c_oflag &= ~ONLCR;  if (flags & 0000020)	termios.c_oflag |= ONLCR;  /* XTABS	- forced on if XTABS */  termios.c_oflag &= ~XTABS;  if (flags & 0006000)	termios.c_oflag |= XTABS;  /* CLOCAL	- not changed */  /* CREAD	- forced on (receiver is always enabled) */  termios.c_cflag |= CREAD;  /* CSIZE	- CS5-CS8 correspond directly to BITS5-BITS8 */  termios.c_cflag = (termios.c_cflag & ~CSIZE) | ((flags & 0001400) >> (8-2));  /* CSTOPB	- not changed */  /* HUPCL	- not changed */  /* PARENB	- set if EVENP or ODDP is set */  termios.c_cflag &= ~PARENB;  if (flags & (0000200|0000100))	termios.c_cflag |= PARENB;  /* PARODD	- set if ODDP is set */  termios.c_cflag &= ~PARODD;  if (flags & 0000100)	termios.c_cflag |= PARODD;  /* Local flags */  /* ECHO		- set if ECHO is set */  termios.c_lflag &= ~ECHO;  if (flags & 0000010)	termios.c_lflag |= ECHO;  /* ECHOE	- not changed */  /* ECHOK	- not changed */  /* ECHONL	- not changed */  /* ICANON	- set if neither CBREAK nor RAW */  termios.c_lflag &= ~ICANON;  if (!(flags & (0000002|0000040)))	termios.c_lflag |= ICANON;  /* IEXTEN	- set if not RAW */  /* ISIG	- set if not RAW */  termios.c_lflag &= ~(IEXTEN|ISIG);  if (!(flags & 0000040))	termios.c_lflag |= (IEXTEN|ISIG);  /* NOFLSH	- not changed */  /* TOSTOP	- not changed */  tp->tty_termios = termios;  setattr(tp);  return(OK);}/*===========================================================================* *				compat_setc				     * *===========================================================================*/PRIVATE int compat_setc(tp, tc)tty_t *tp;struct tchars *tc;{/* Translate an old TIOCSETC to the termios equivalent. */  struct termios termios;  termios = tp->tty_termios;  termios.c_cc[VINTR] = tc->t_intrc;  termios.c_cc[VQUIT] = tc->t_quitc;  termios.c_cc[VSTART] = tc->t_startc;  termios.c_cc[VSTOP] = tc->t_stopc;  termios.c_cc[VEOL] = tc->t_brkc;  termios.c_cc[VEOF] = tc->t_eofc;  tp->tty_termios = termios;  setattr(tp);  return(OK);}/* Table of termios line speed to sgtty line speed translations.   All termios * speeds are present even if sgtty didn't know about them.  (Now it does.) */PRIVATE struct s2s {  speed_t	tspd;  u8_t		sgspd;} ts2sgs[] = {  { B0,		  0 },  { B50,	 50 },  { B75,	 75 },  { B110,	  1 },  { B134,	134 },  { B200,	  2 },  { B300,	  3 },  { B600,	  6 },  { B1200,	 12 },  { B1800,	 18 },  { B2400,	 24 },  { B4800,	 48 },  { B9600,	 96 },  { B19200,	192 },  { B38400,	195 },  { B57600,	194 },  { B115200,	193 },};/*===========================================================================* *				tspd2sgspd				     * *===========================================================================*/PRIVATE int tspd2sgspd(tspd)speed_t tspd;{/* Translate a termios speed to sgtty speed. */  struct s2s *s;  for (s = ts2sgs; s < ts2sgs + sizeof(ts2sgs)/sizeof(ts2sgs[0]); s++) {	if (s->tspd == tspd) return(s->sgspd);  }  return 96;}/*===========================================================================* *				sgspd2tspd				     * *===========================================================================*/PRIVATE speed_t sgspd2tspd(sgspd)int sgspd;{/* Translate a sgtty speed to termios speed. */  struct s2s *s;  for (s = ts2sgs; s < ts2sgs + sizeof(ts2sgs)/sizeof(ts2sgs[0]); s++) {	if (s->sgspd == sgspd) return(s->tspd);  }  return B9600;}#if ENABLE_BINCOMPAT/*===========================================================================* *				do_ioctl_compat				     * *===========================================================================*/PRIVATE void do_ioctl_compat(tp, m_ptr)tty_t *tp;message *m_ptr;{/* Handle the old sgtty ioctl's that packed the sgtty or tchars struct into * the Minix message.  Efficient then, troublesome now. */  int minor, proc, func, result, r;  long flags, erki, spek;  u8_t erase, kill, intr, quit, xon, xoff, brk, eof, ispeed, ospeed;  struct sgttyb sg;  struct tchars tc;  message reply_mess;  minor = m_ptr->TTY_LINE;  proc = m_ptr->PROC_NR;  func = m_ptr->REQUEST;  spek = m_ptr->m2_l1;  flags = m_ptr->m2_l2;  switch(func)  {    case (('t'<<8) | 8):	/* TIOCGETP */	r = compat_getp(tp, &sg);	erase = sg.sg_erase;	kill = sg.sg_kill;	ispeed = sg.sg_ispeed;	ospeed = sg.sg_ospeed;	flags = sg.sg_flags;	erki = ((long)ospeed<<24) | ((long)ispeed<<16) | ((long)erase<<8) |kill;	break;    case (('t'<<8) | 18):	/* TIOCGETC */	r = compat_getc(tp, &tc);	intr = tc.t_intrc;	quit = tc.t_quitc;	xon = tc.t_startc;	xoff = tc.t_stopc;	brk = tc.t_brkc;	eof = tc.t_eofc;	erki = ((long)intr<<24) | ((long)quit<<16) | ((long)xon<<8) | xoff;	flags = (eof << 8) | brk;	break;    case (('t'<<8) | 17):	/* TIOCSETC */	tc.t_stopc = (spek >> 0) & 0xFF;	tc.t_startc = (spek >> 8) & 0xFF;	tc.t_quitc = (spek >> 16) & 0xFF;	tc.t_intrc = (spek >> 24) & 0xFF;	tc.t_brkc = (flags >> 0) & 0xFF;	tc.t_eofc = (flags >> 8) & 0xFF;	r = compat_setc(tp, &tc);	break;    case (('t'<<8) | 9):	/* TIOCSETP */	sg.sg_erase = (spek >> 8) & 0xFF;	sg.sg_kill = (spek >> 0) & 0xFF;	sg.sg_ispeed = (spek >> 16) & 0xFF;	sg.sg_ospeed = (spek >> 24) & 0xFF;	sg.sg_flags = flags;	r = compat_setp(tp, &sg);	break;    default:	r = ENOTTY;  }  reply_mess.m_type = TASK_REPLY;  reply_mess.REP_PROC_NR = m_ptr->PROC_NR;  reply_mess.REP_STATUS = r;  reply_mess.m2_l1 = erki;  reply_mess.m2_l2 = flags;  send(m_ptr->m_source, &reply_mess);}#endif /* ENABLE_BINCOMPAT */#endif /* ENABLE_SRCCOMPAT || ENABLE_BINCOMPAT */

⌨️ 快捷键说明

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