読者です 読者をやめる 読者になる 読者になる

by shigemk2

当面は技術的なことしか書かない

入力されたデータの読み込み

Unix

入力されたデータは以下の流れでユーザ空間に読み込まれる

  1. ユーザプログラムが端末に対してreadシステムコールを発行
  2. tty.t_rawqからデータを読み出し、tty.t_canqへデータを移す
  3. 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);
}