入力されたデータは以下の流れでユーザ空間に読み込まれる
- ユーザプログラムが端末に対してreadシステムコールを発行
- tty.t_rawqからデータを読み出し、tty.t_canqへデータを移す
- tty.t_canqのデータをユーザ空間に呼び出す
klread(データをユーザ空間に読み込む)→ttread(tty.t_canqからユーザ空間にデータを送り込む)
/* * Called from device's read routine after it has * calculated the tty-structure given as argument. * The pc is backed up for the duration of this call. * In case of a caught interrupt, an RTI will re-execute. */ ttread(atp) struct tty *atp; { register struct tty *tp; tp = atp; if ((tp->t_state&CARR_ON)==0) return; /* passcを使ってtty.t_canqのデータをユーザ空間に送り込む */ if (tp->t_canq.c_cc || canon(tp)) while (tp->t_canq.c_cc && passc(getc(&tp->t_canq))>=0); }
canon
tty.t_rawqからtty.t_canqへデータを送り込む tty.t_rawqにデータが追加されたら1が変える
/* * transfer raw input list to canonical list, * doing erase-kill processing and handling escapes. * It waits until a full line has been typed in cooked mode, * or until any character has been typed in raw mode. */ canon(atp) struct tty *atp; { register char *bp; char *bp1; register struct tty *tp; register int c; tp = atp; spl5(); while (tp->t_delct==0) { if ((tp->t_state&CARR_ON)==0) return(0); sleep(&tp->t_rawq, TTIPRI); } spl0(); loop: bp = &canonb[2]; while ((c=getc(&tp->t_rawq)) >= 0) { if (c==0377) { tp->t_delct--; break; } if ((tp->t_flags&RAW)==0) { if (bp[-1]!='\\') { if (c==tp->t_erase) { if (bp > &canonb[2]) bp--; continue; } if (c==tp->t_kill) goto loop; if (c==CEOT) continue; } else if (maptab[c] && (maptab[c]==c || (tp->t_flags&LCASE))) { if (bp[-2] != '\\') c = maptab[c]; bp--; } } *bp++ = c; if (bp>=canonb+CANBSIZ) break; } bp1 = bp; bp = &canonb[2]; c = &tp->t_canq; while (bp<bp1) putc(*bp++, c); return(1); }