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 + -
显示快捷键?