code:canon - ikarishinjieva/unixV6-code-analyze-chs GitHub Wiki

Source

  • 取出tty原始队列中的内容(直到遇到定界符或者canonb数组已满),经过处理后导入tty非原始队列
  • 传入1个参数:
  • 返回值:
    • 若导入成功,返回1
    • 否则,返回0
8269 /* transfer raw input list to canonical list,

8270  * doing erase-kill processing and handling escapes.

8271  * It waits until a full line has been typed in cooked mode,

8272  * or until any character has been typed in raw mode.

8273  */

8274 canon(atp)

8275 struct tty *atp;

8276 {

8277     register char *bp;

8278     char *bp1;

8279     register struct tty *tp;

8280     register int c;

8282     tp = atp;

8283     spl5();

  • 处理机优先级设为5
8284     while (tp->t_delct==0) {

8285           if ((tp->t_state&CARR_ON)==0)

8286                    return(0);

8287           sleep(&tp->t_rawq, TTIPRI);

8288     }

8289     spl0();
8291     bp = &canonb[2];
  • 用bp指示字符插入canonb数组的位置,此处以数组第三个字符的位置为开头,这样做的原因是防止后面bp[-2]寻址时溢出
  • 8284 - 8318:
  • 这是一个循环,每次从原始队列中取一个字符,并且进行相应处理
8292     while ((c=getc(&tp->t_rawq)) >= 0) {

8293           if (c==0377) {

8294                    tp->t_delct--;

8295                    break;

8296           }

  • 若取出的是定界符,则定界符数减1
  • 退出循环
8297           if ((tp->t_flags&RAW)==0) {

8298                     if (bp[-1]!='\\') {

  • 若终端使用原始方式工作,且前一个字符不是转意字符
8299                              if (c==tp->t_erase) {

8300                                        if (bp > &canonb[2])

8301                                              bp--;

8302                                        continue;

8303                     }

  • 若读入的为'擦去字符'编辑功能字符,且有可以删除的字符
    • 则bp退回一个字符位置,开始下一次循环
8304                              if (c==tp->t_kill)

8305                                    goto loop;

  • 若读入的为'删除当前行'编辑功能字符
    • 放弃当前积累起的所有字符,回到8290行,从头开始
8306                              if (c==CEOT)

8307                                    continue;

  • 若读入的字符为'eot'编辑功能字符
    • 忽略该字符该字符,开始下一次循环
8308                    } else
  • 8309 - 8314:是对前一字符是转移字符的处理
8309     if (maptab[c] && (maptab[c]==c || (tp->t_flags&LCASE))) {

8310                          if (bp[-2] != '\\')

8311                                   c = maptab[c];

  • 进行转义字符的处理
8312                          bp--;
  • bp退回一个字符位置
8313                    }

8314           }

8315            *bp++ = c;

  • 将读出的字符放入canonb数组中,位由bp所指示
8316           if (bp>=canonb+CANBSIZ)

8317                    break;

  • canonb数组已满,则退出循环
8318     }

8319     bp1 = bp;

8320     bp = &canonb[2];

8321     c = &tp->t_canq;

8322     while (bp<bp1)

8323           putc(*bp++, c);

  • canonb数组中的字符一个个全部加入到非原始输入队列中

8324     return(1);

8325 }

8326 /* ------------------------- */

Caller

⚠️ **GitHub.com Fallback** ⚠️