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

Source

  • 向tty输出一个字符
  • 输入2个参数 ac , atp
    • ac : 欲输出的字符
    • atp : 指定tty

8367 /* put character on TTY output queue, adding delays,

8368  * expanding tabs, and handling the CR/NL bit.

8369  * It is called both from the top half for output, and from

8370  * interrupt level for echoing.

8371  * The arguments are the character and the tty structure.

8372  */

8373 ttyoutput(ac, tp)

8374 struct tty *tp;

8375 {

8376     register int c;

8377     register struct tty *rtp;

8378     register char *colp;

8379     int ctype;

8380

8381     rtp= tp;

8382     c = ac&0177;

8383     /* Ignore EOT in normal mode to avoid hanging up

8384      * certain terminals.

8385      */

8386     if (c==004 && (rtp->t_flags&RAW)==0)

8387          return;

  • 若 c为EOF(文件结束字符),且tty不是原始模式,则直接返回,不做处理
8388     /* Turn tabs to spaces as required

8389      */

8390     if (c==’\t’ && rtp->t_flags&XTABS) {

8391          do

8392           ttyoutput(’ ’, rtp);

8393          while (rtp->t_col&07);

8394          return;

8395     }

  • 若 c为制表符,且tty无法处理制表符,则将制表符换成若干空格(对其列 到8的倍数)
8396     /* for upper-case-only terminals,

8397      * generate escapes.

8398      */

8399     if (rtp->t_flags&LCASE) {

8400          colp = "({)}!|^~’‘";

8401          while(*colp++)

8402               if(c == *colp++) {

8403                ttyoutput(’\\’, rtp);

8404                c = colp[-2];

8405                break;

8406               }

8407          if (’a’<=c && c<=’z’)

8408               c =+ ’A’ - ’a’;

8409     }

若 只支持 64字符 ASCII 子集,完成以下字符转义
    • a - z → A - Z
    • { → \(
    • } → \)
    • | → \!
    • ~ → \^
    • ‘ → \’
8410     /* turn <nl></nl> to <cr></cr><lf></lf> if desired.

8411      */

8412     if (c==’ \n’ && rtp->t_flags&CRMOD)

8413          ttyoutput(’\r’, rtp);

  • 若tty 使用了CR换行,则
\n → \r \n
8414     if (putc(c, &rtp->t_outq))

8415          return;

  • 若 c 输出到tty输出队列失败,直接返回
  • 以下开始计算 输出c 后的 设备延迟 (设备需要一定时间输出字符)
  • 详细说明参看 LIONS 源代码分析 25.4.5 (难得LIONS写得那么详细清楚...)
8416     /* Calculate delays.

8417      * The numbers here represent clock ticks

8418      * and are not necessarily optimal for all terminals.

8419      * The delays are indicated by characters above 0200,

8420      * thus (unfortunately) restricting the transmission

8421      * path to 7 bits.

8422      */

8423      colp = &rtp->t_col;

8424      ctype = partab[c];

8425      c = 0;

8426     switch(ctype&077) {

8427          /* ordinary */

8428          case 0:

8429           (*colp)++;

8430          /* non-printing */

8431          case 1:

8432           break;

8433          /* backspace */

8434          case 2:

8435           if (*colp)

8436                (*colp)--;

8437           break;

8438          /* newline */

8439          case 3:

8440           ctype = (rtp->t_flags >> 8) & 03;

8441           if(ctype == 1) { /* tty 37 */

8442                if (*colp)

8443                     c = max((*colp>>4) + 3, 6);

8444           } else

8445                if(ctype == 2) { /* vt05 */

8446                     c = 6;

8447                }

8448            *colp = 0;

8449           break;

8450          /* tab */

8451          case 4:

8452           ctype = (rtp->t_flags >> 10) & 03;

8453           if(ctype == 1) { /* tty 37 */

8454                c = 1 - (*colp | ~07);

8455                if(c < 5)

8456                     c = 0;

8457           }

8458            *colp =| 07;

8459           (*colp)++;

8460           break;

8461          /* vertical motion */

8462          case 5:

8463           if(rtp->t_flags & VTDELAY) /* tty 37 */

8464           c = 0177;

8465           break;

8466          /* carriage return */

8467          case 6:

8468           ctype = (rtp->t_flags >> 12) & 03;

8469           if(ctype == 1) { /* tn 300 */

8470                c = 5;

8471           } else

8472                if(ctype == 2) { /* ti 700 */

8473                     c = 10;

8474                }

8475            *colp = 0;

8476     }

8477     if(c)

8478          putc(c|0200, &rtp->t_outq);

8479 }

8480 /* ------------------------- */

Caller

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