1: #
   2: /*
   3:  * general TTY subroutines
   4:  */
   5: #include "../h/param.h"
   6: #include "../h/systm.h"
   7: #include "../h/dir.h"
   8: #include "../h/user.h"
   9: #include "../h/tty.h"
  10: #include "../h/proc.h"
  11: #include "../h/mx.h"
  12: #include "../h/inode.h"
  13: #include "../h/file.h"
  14: #include "../h/reg.h"
  15: #include "../h/conf.h"
  16: 
  17: char    partab[];
  18: 
  19: 
  20: /*
  21:  * Input mapping table-- if an entry is non-zero, when the
  22:  * corresponding character is typed preceded by "\" the escape
  23:  * sequence is replaced by the table value.  Mostly used for
  24:  * upper-case only terminals.
  25:  */
  26: 
  27: char    maptab[] ={
  28:     000,000,000,000,000,000,000,000,
  29:     000,000,000,000,000,000,000,000,
  30:     000,000,000,000,000,000,000,000,
  31:     000,000,000,000,000,000,000,000,
  32:     000,'|',000,000,000,000,000,'`',
  33:     '{','}',000,000,000,000,000,000,
  34:     000,000,000,000,000,000,000,000,
  35:     000,000,000,000,000,000,000,000,
  36:     000,000,000,000,000,000,000,000,
  37:     000,000,000,000,000,000,000,000,
  38:     000,000,000,000,000,000,000,000,
  39:     000,000,000,000,000,000,'~',000,
  40:     000,'A','B','C','D','E','F','G',
  41:     'H','I','J','K','L','M','N','O',
  42:     'P','Q','R','S','T','U','V','W',
  43:     'X','Y','Z',000,000,000,000,000,
  44: };
  45: 
  46: 
  47: /*
  48:  * shorthand
  49:  */
  50: #define q1  tp->t_rawq
  51: #define q2  tp->t_canq
  52: #define q3  tp->t_outq
  53: #define q4  tp->t_un.t_ctlq
  54: 
  55: 
  56: /*
  57:  * routine called on first teletype open.
  58:  * establishes a process group for distribution
  59:  * of quits and interrupts from the tty.
  60:  */
  61: ttyopen(dev, tp)
  62: dev_t dev;
  63: register struct tty *tp;
  64: {
  65:     register struct proc *pp;
  66: 
  67:     pp = u.u_procp;
  68:     tp->t_dev = dev;
  69:     if(pp->p_pgrp == 0) {
  70:         u.u_ttyp = tp;
  71:         u.u_ttyd = dev;
  72:         if (tp->t_pgrp==0)
  73:             tp->t_pgrp = pp->p_pid;
  74:         pp->p_pgrp = tp->t_pgrp;
  75:     }
  76:     tp->t_state &= ~WOPEN;
  77:     tp->t_state |= ISOPEN;
  78: }
  79: 
  80: 
  81: /*
  82:  * set default control characters.
  83:  */
  84: ttychars(tp)
  85: register struct tty *tp;
  86: {
  87:     tun.t_intrc = CINTR;
  88:     tun.t_quitc = CQUIT;
  89:     tun.t_startc = CSTART;
  90:     tun.t_stopc = CSTOP;
  91:     tun.t_eofc = CEOT;
  92:     tun.t_brkc = CBRK;
  93:     tp->t_erase = CERASE;
  94:     tp->t_kill = CKILL;
  95: }
  96: 
  97: /*
  98:  * clean tp on last close
  99:  */
 100: ttyclose(tp)
 101: register struct tty *tp;
 102: {
 103: 
 104:     tp->t_pgrp = 0;
 105:     wflushtty(tp);
 106:     tp->t_state = 0;
 107: }
 108: 
 109: /*
 110:  * stty/gtty writearound
 111:  */
 112: stty()
 113: {
 114:     u.u_arg[2] = u.u_arg[1];
 115:     u.u_arg[1] = TIOCSETP;
 116:     ioctl();
 117: }
 118: 
 119: gtty()
 120: {
 121:     u.u_arg[2] = u.u_arg[1];
 122:     u.u_arg[1] = TIOCGETP;
 123:     ioctl();
 124: }
 125: 
 126: /*
 127:  * ioctl system call
 128:  * Check legality, execute common code, and switch out to individual
 129:  * device routine.
 130:  */
 131: ioctl()
 132: {
 133:     register struct file *fp;
 134:     register struct inode *ip;
 135:     register struct a {
 136:         int fdes;
 137:         int cmd;
 138:         caddr_t cmarg;
 139:     } *uap;
 140:     register dev_t dev;
 141:     register fmt;
 142: 
 143:     uap = (struct a *)u.u_ap;
 144:     if ((fp = getf(uap->fdes)) == NULL)
 145:         return;
 146:     if (uap->cmd==FIOCLEX) {
 147:         u.u_pofile[uap->fdes] |= EXCLOSE;
 148:         return;
 149:     }
 150:     if (uap->cmd==FIONCLEX) {
 151:         u.u_pofile[uap->fdes] &= ~EXCLOSE;
 152:         return;
 153:     }
 154:     ip = fp->f_inode;
 155:     fmt = ip->i_mode & IFMT;
 156:     if (fmt != IFCHR && fmt != IFMPC) {
 157:         u.u_error = ENOTTY;
 158:         return;
 159:     }
 160:     dev = (dev_t)ip->i_un.i_rdev;
 161:     (*cdevsw[major(dev)].d_ioctl)(dev, uap->cmd, uap->cmarg, fp->f_flag);
 162: }
 163: 
 164: /*
 165:  * Common code for several tty ioctl commands
 166:  */
 167: ttioccomm(com, tp, addr, dev)
 168: register struct tty *tp;
 169: caddr_t addr;
 170: {
 171:     unsigned t;
 172:     struct ttiocb iocb;
 173:     extern int nldisp;
 174: 
 175:     switch(com) {
 176: 
 177:     /*
 178: 	 * get discipline number
 179: 	 */
 180:     case TIOCGETD:
 181:         t = tp->t_line;
 182:         if (copyout((caddr_t)&t, addr, sizeof(t)))
 183:             u.u_error = EFAULT;
 184:         break;
 185: 
 186:     /*
 187: 	 * set line discipline
 188: 	 */
 189:     case TIOCSETD:
 190:         if (copyin(addr, (caddr_t)&t, sizeof(t))) {
 191:             u.u_error = EFAULT;
 192:             break;
 193:         }
 194:         if (t >= nldisp) {
 195:             u.u_error = ENXIO;
 196:             break;
 197:         }
 198:         if (tp->t_line)
 199:             (*linesw[tp->t_line].l_close)(tp);
 200:         if (t)
 201:             (*linesw[t].l_open)(dev, tp, addr);
 202:         if (u.u_error==0)
 203:             tp->t_line = t;
 204:         break;
 205: 
 206:     /*
 207: 	 * prevent more opens on channel
 208: 	 */
 209:     case TIOCEXCL:
 210:         tp->t_state |= XCLUDE;
 211:         break;
 212:     case TIOCNXCL:
 213:         tp->t_state &= ~XCLUDE;
 214:         break;
 215: 
 216:     /*
 217: 	 * Set new parameters
 218: 	 */
 219:     case TIOCSETP:
 220:         wflushtty(tp);
 221:     case TIOCSETN:
 222:         if (copyin(addr, (caddr_t)&iocb, sizeof(iocb))) {
 223:             u.u_error = EFAULT;
 224:             return(1);
 225:         }
 226:         tp->t_ispeed = iocb.ioc_ispeed;
 227:         tp->t_ospeed = iocb.ioc_ospeed;
 228:         tp->t_erase = iocb.ioc_erase;
 229:         tp->t_kill = iocb.ioc_kill;
 230:         tp->t_flags = iocb.ioc_flags;
 231:         break;
 232: 
 233:     /*
 234: 	 * send current parameters to user
 235: 	 */
 236:     case TIOCGETP:
 237:         iocb.ioc_ispeed = tp->t_ispeed;
 238:         iocb.ioc_ospeed = tp->t_ospeed;
 239:         iocb.ioc_erase = tp->t_erase;
 240:         iocb.ioc_kill = tp->t_kill;
 241:         iocb.ioc_flags = tp->t_flags;
 242:         if (copyout((caddr_t)&iocb, addr, sizeof(iocb)))
 243:             u.u_error = EFAULT;
 244:         break;
 245: 
 246:     /*
 247: 	 * Hang up line on last close
 248: 	 */
 249: 
 250:     case TIOCHPCL:
 251:         tp->t_state |= HUPCLS;
 252:         break;
 253: 
 254:     case TIOCFLUSH:
 255:         flushtty(tp);
 256:         break;
 257: 
 258:     /*
 259: 	 * ioctl entries to line discipline
 260: 	 */
 261:     case DIOCSETP:
 262:     case DIOCGETP:
 263:         (*linesw[tp->t_line].l_ioctl)(com, tp, addr);
 264:         break;
 265: 
 266:     /*
 267: 	 * set and fetch special characters
 268: 	 */
 269:     case TIOCSETC:
 270:         if (copyin(addr, (caddr_t)&tun, sizeof(struct tc)))
 271:             u.u_error = EFAULT;
 272:         break;
 273: 
 274:     case TIOCGETC:
 275:         if (copyout((caddr_t)&tun, addr, sizeof(struct tc)))
 276:             u.u_error = EFAULT;
 277:         break;
 278: 
 279:     default:
 280:         return(0);
 281:     }
 282:     return(1);
 283: }
 284: 
 285: /*
 286:  * Wait for output to drain, then flush input waiting.
 287:  */
 288: wflushtty(tp)
 289: register struct tty *tp;
 290: {
 291: 
 292:     spl5();
 293:     while (tp->t_outq.c_cc && tp->t_state&CARR_ON) {
 294:         (*tp->t_oproc)(tp);
 295:         tp->t_state |= ASLEEP;
 296:         sleep((caddr_t)&tp->t_outq, TTOPRI);
 297:     }
 298:     flushtty(tp);
 299:     spl0();
 300: }
 301: 
 302: /*
 303:  * flush all TTY queues
 304:  */
 305: flushtty(tp)
 306: register struct tty *tp;
 307: {
 308:     register s;
 309: 
 310:     while (getc(&tp->t_canq) >= 0)
 311:         ;
 312:     wakeup((caddr_t)&tp->t_rawq);
 313:     wakeup((caddr_t)&tp->t_outq);
 314:     s = spl6();
 315:     tp->t_state &= ~TTSTOP;
 316:     (*cdevsw[major(tp->t_dev)].d_stop)(tp);
 317:     while (getc(&tp->t_outq) >= 0)
 318:         ;
 319:     while (getc(&tp->t_rawq) >= 0)
 320:         ;
 321:     tp->t_delct = 0;
 322:     splx(s);
 323: }
 324: 
 325: 
 326: 
 327: /*
 328:  * transfer raw input list to canonical list,
 329:  * doing erase-kill processing and handling escapes.
 330:  * It waits until a full line has been typed in cooked mode,
 331:  * or until any character has been typed in raw mode.
 332:  */
 333: canon(tp)
 334: register struct tty *tp;
 335: {
 336:     register char *bp;
 337:     char *bp1;
 338:     register int c;
 339:     int mc;
 340: 
 341:     spl5();
 342:     while ((tp->t_flags&(RAW|CBREAK))==0 && tp->t_delct==0
 343:         || (tp->t_flags&(RAW|CBREAK))!=0 && tp->t_rawq.c_cc==0) {
 344:         if ((tp->t_state&CARR_ON)==0 || tp->t_chan!=NULL) {
 345:             return(0);
 346:         }
 347:         sleep((caddr_t)&tp->t_rawq, TTIPRI);
 348:     }
 349:     spl0();
 350: loop:
 351:     bp = &canonb[2];
 352:     while ((c=getc(&tp->t_rawq)) >= 0) {
 353:         if ((tp->t_flags&(RAW|CBREAK))==0) {
 354:             if (c==0377) {
 355:                 tp->t_delct--;
 356:                 break;
 357:             }
 358:             if (bp[-1]!='\\') {
 359:                 if (c==tp->t_erase) {
 360:                     if (bp > &canonb[2])
 361:                         bp--;
 362:                     continue;
 363:                 }
 364:                 if (c==tp->t_kill)
 365:                     goto loop;
 366:                 if (c==tun.t_eofc)
 367:                     continue;
 368:             } else {
 369:                 mc = maptab[c];
 370:                 if (c==tp->t_erase || c==tp->t_kill)
 371:                     mc = c;
 372:                 if (mc && (mc==c || (tp->t_flags&LCASE))) {
 373:                     if (bp[-2] != '\\')
 374:                         c = mc;
 375:                     bp--;
 376:                 }
 377:             }
 378:         }
 379:         *bp++ = c;
 380:         if (bp>=canonb+CANBSIZ)
 381:             break;
 382:     }
 383:     bp1 = &canonb[2];
 384:     b_to_q(bp1, bp-bp1, &tp->t_canq);
 385: 
 386:     if (tp->t_state&TBLOCK && tp->t_rawq.c_cc < TTYHOG/5) {
 387:         if (putc(tun.t_startc, &tp->t_outq)==0) {
 388:             tp->t_state &= ~TBLOCK;
 389:             ttstart(tp);
 390:         }
 391:         tp->t_char = 0;
 392:     }
 393: 
 394:     return(bp-bp1);
 395: }
 396: 
 397: 
 398: /*
 399:  * block transfer input handler.
 400:  */
 401: ttyrend(tp, pb, pe)
 402: register struct tty *tp;
 403: register char *pb, *pe;
 404: {
 405:     int tandem;
 406: 
 407:     tandem = tp->t_flags&TANDEM;
 408:     if (tp->t_flags&RAW) {
 409:         b_to_q(pb, pe-pb, &tp->t_rawq);
 410:         if (tp->t_chan)
 411:             sdata(tp->t_chan); else
 412:             wakeup((caddr_t)&tp->t_rawq);
 413:     } else {
 414:         tp->t_flags &= ~TANDEM;
 415:         while (pb < pe)
 416:             ttyinput(*pb++, tp);
 417:         tp->t_flags |= tandem;
 418:     }
 419:     if (tandem)
 420:         ttyblock(tp);
 421: }
 422: 
 423: /*
 424:  * Place a character on raw TTY input queue, putting in delimiters
 425:  * and waking up top half as needed.
 426:  * Also echo if required.
 427:  * The arguments are the character and the appropriate
 428:  * tty structure.
 429:  */
 430: ttyinput(c, tp)
 431: register c;
 432: register struct tty *tp;
 433: {
 434:     register int t_flags;
 435:     register struct chan *cp;
 436: 
 437:     tk_nin += 1;
 438:     c &= 0377;
 439:     t_flags = tp->t_flags;
 440:     if (t_flags&TANDEM)
 441:         ttyblock(tp);
 442:     if ((t_flags&RAW)==0) {
 443:         c &= 0177;
 444:         if (tp->t_state&TTSTOP) {
 445:             if (c==tun.t_startc) {
 446:                 tp->t_state &= ~TTSTOP;
 447:                 ttstart(tp);
 448:                 return;
 449:             }
 450:             if (c==tun.t_stopc)
 451:                 return;
 452:             tp->t_state &= ~TTSTOP;
 453:             ttstart(tp);
 454:         } else {
 455:             if (c==tun.t_stopc) {
 456:                 tp->t_state |= TTSTOP;
 457:                 (*cdevsw[major(tp->t_dev)].d_stop)(tp);
 458:                 return;
 459:             }
 460:             if (c==tun.t_startc)
 461:                 return;
 462:         }
 463:         if (c==tun.t_quitc || c==tun.t_intrc) {
 464:             flushtty(tp);
 465:             c = (c==tun.t_intrc) ? SIGINT:SIGQUIT;
 466:             if (tp->t_chan)
 467:                 scontrol(tp->t_chan, M_SIG, c);
 468:             else
 469:                 signal(tp->t_pgrp, c);
 470:             return;
 471:         }
 472:         if (c=='\r' && t_flags&CRMOD)
 473:             c = '\n';
 474:     }
 475:     if (tp->t_rawq.c_cc>TTYHOG) {
 476:         flushtty(tp);
 477:         return;
 478:     }
 479:     if (t_flags&LCASE && c>='A' && c<='Z')
 480:         c += 'a'-'A';
 481:     putc(c, &tp->t_rawq);
 482:     if (t_flags&(RAW|CBREAK)||(c=='\n'||c==tun.t_eofc||c==tun.t_brkc)) {
 483:         if ((t_flags&(RAW|CBREAK))==0 && putc(0377, &tp->t_rawq)==0)
 484:             tp->t_delct++;
 485:         if ((cp=tp->t_chan)!=NULL)
 486:             sdata(cp); else
 487:             wakeup((caddr_t)&tp->t_rawq);
 488:     }
 489:     if (t_flags&ECHO) {
 490:         ttyoutput(c, tp);
 491:         if (c==tp->t_kill && (t_flags&(RAW|CBREAK))==0)
 492:             ttyoutput('\n', tp);
 493:         ttstart(tp);
 494:     }
 495: }
 496: 
 497: 
 498: /*
 499:  * Send stop character on input overflow.
 500:  */
 501: ttyblock(tp)
 502: register struct tty *tp;
 503: {
 504: register x;
 505:     x = q1.c_cc + q2.c_cc;
 506:     if (q1.c_cc > TTYHOG) {
 507:         flushtty(tp);
 508:         tp->t_state &= ~TBLOCK;
 509:     }
 510:     if (x >= TTYHOG/2) {
 511:         if (putc(tun.t_stopc, &tp->t_outq)==0) {
 512:             tp->t_state |= TBLOCK;
 513:             tp->t_char++;
 514:             ttstart(tp);
 515:         }
 516:     }
 517: }
 518: 
 519: /*
 520:  * put character on TTY output queue, adding delays,
 521:  * expanding tabs, and handling the CR/NL bit.
 522:  * It is called both from the top half for output, and from
 523:  * interrupt level for echoing.
 524:  * The arguments are the character and the tty structure.
 525:  */
 526: ttyoutput(c, tp)
 527: register c;
 528: register struct tty *tp;
 529: {
 530:     register char *colp;
 531:     register ctype;
 532: 
 533:     tk_nout += 1;
 534:     /*
 535: 	 * Ignore EOT in normal mode to avoid hanging up
 536: 	 * certain terminals.
 537: 	 * In raw mode dump the char unchanged.
 538: 	 */
 539: 
 540:     if ((tp->t_flags&RAW)==0) {
 541:         c &= 0177;
 542:         if (c==CEOT)
 543:             return;
 544:     } else {
 545:         putc(c, &tp->t_outq);
 546:         return;
 547:     }
 548: 
 549:     /*
 550: 	 * Turn tabs to spaces as required
 551: 	 */
 552:     if (c=='\t' && (tp->t_flags&TBDELAY)==XTABS) {
 553:         c = 8;
 554:         do
 555:             ttyoutput(' ', tp);
 556:         while (--c >= 0 && tp->t_col&07);
 557:         return;
 558:     }
 559:     /*
 560: 	 * for upper-case-only terminals,
 561: 	 * generate escapes.
 562: 	 */
 563:     if (tp->t_flags&LCASE) {
 564:         colp = "({)}!|^~'`";
 565:         while(*colp++)
 566:             if(c == *colp++) {
 567:                 ttyoutput('\\', tp);
 568:                 c = colp[-2];
 569:                 break;
 570:             }
 571:         if ('a'<=c && c<='z')
 572:             c += 'A' - 'a';
 573:     }
 574:     /*
 575: 	 * turn <nl> to <cr><lf> if desired.
 576: 	 */
 577:     if (c=='\n' && tp->t_flags&CRMOD)
 578:         ttyoutput('\r', tp);
 579:     putc(c, &tp->t_outq);
 580:     /*
 581: 	 * Calculate delays.
 582: 	 * The numbers here represent clock ticks
 583: 	 * and are not necessarily optimal for all terminals.
 584: 	 * The delays are indicated by characters above 0200.
 585: 	 * In raw mode there are no delays and the
 586: 	 * transmission path is 8 bits wide.
 587: 	 */
 588:     colp = &tp->t_col;
 589:     ctype = partab[c];
 590:     c = 0;
 591:     switch (ctype&077) {
 592: 
 593:     /* ordinary */
 594:     case 0:
 595:         (*colp)++;
 596: 
 597:     /* non-printing */
 598:     case 1:
 599:         break;
 600: 
 601:     /* backspace */
 602:     case 2:
 603:         if (*colp)
 604:             (*colp)--;
 605:         break;
 606: 
 607:     /* newline */
 608:     case 3:
 609:         ctype = (tp->t_flags >> 8) & 03;
 610:         if(ctype == 1) { /* tty 37 */
 611:             if (*colp)
 612:                 c = max(((unsigned)*colp>>4) + 3, (unsigned)6);
 613:         } else
 614:         if(ctype == 2) { /* vt05 */
 615:             c = 6;
 616:         }
 617:         *colp = 0;
 618:         break;
 619: 
 620:     /* tab */
 621:     case 4:
 622:         ctype = (tp->t_flags >> 10) & 03;
 623:         if(ctype == 1) { /* tty 37 */
 624:             c = 1 - (*colp | ~07);
 625:             if(c < 5)
 626:                 c = 0;
 627:         }
 628:         *colp |= 07;
 629:         (*colp)++;
 630:         break;
 631: 
 632:     /* vertical motion */
 633:     case 5:
 634:         if(tp->t_flags & VTDELAY) /* tty 37 */
 635:             c = 0177;
 636:         break;
 637: 
 638:     /* carriage return */
 639:     case 6:
 640:         ctype = (tp->t_flags >> 12) & 03;
 641:         if(ctype == 1) { /* tn 300 */
 642:             c = 5;
 643:         } else if(ctype == 2) { /* ti 700 */
 644:             c = 10;
 645:         }
 646:         *colp = 0;
 647:     }
 648:     if(c)
 649:         putc(c|0200, &tp->t_outq);
 650: }
 651: 
 652: /*
 653:  * Restart typewriter output following a delay
 654:  * timeout.
 655:  * The name of the routine is passed to the timeout
 656:  * subroutine and it is called during a clock interrupt.
 657:  */
 658: ttrstrt(tp)
 659: register struct tty *tp;
 660: {
 661: 
 662:     tp->t_state &= ~TIMEOUT;
 663:     ttstart(tp);
 664: }
 665: 
 666: /*
 667:  * Start output on the typewriter. It is used from the top half
 668:  * after some characters have been put on the output queue,
 669:  * from the interrupt routine to transmit the next
 670:  * character, and after a timeout has finished.
 671:  */
 672: ttstart(tp)
 673: register struct tty *tp;
 674: {
 675:     register s;
 676: 
 677:     s = spl5();
 678:     if((tp->t_state&(TIMEOUT|TTSTOP|BUSY)) == 0)
 679:         (*tp->t_oproc)(tp);
 680:     splx(s);
 681: }
 682: 
 683: /*
 684:  * Called from device's read routine after it has
 685:  * calculated the tty-structure given as argument.
 686:  */
 687: ttread(tp)
 688: register struct tty *tp;
 689: {
 690: 
 691:     if ((tp->t_state&CARR_ON)==0)
 692:         return(0);
 693:     if (tp->t_canq.c_cc || canon(tp))
 694:         while (tp->t_canq.c_cc && passc(getc(&tp->t_canq))>=0)
 695:             ;
 696:     return(tp->t_rawq.c_cc + tp->t_canq.c_cc);
 697: }
 698: 
 699: /*
 700:  * Called from the device's write routine after it has
 701:  * calculated the tty-structure given as argument.
 702:  */
 703: caddr_t
 704: ttwrite(tp)
 705: register struct tty *tp;
 706: {
 707:     register c;
 708: 
 709:     if ((tp->t_state&CARR_ON)==0)
 710:         return(NULL);
 711:     while (u.u_count) {
 712:         spl5();
 713:         while (tp->t_outq.c_cc > TTHIWAT) {
 714:             ttstart(tp);
 715:             tp->t_state |= ASLEEP;
 716:             if (tp->t_chan)
 717:                 return((caddr_t)&tp->t_outq);
 718:             sleep((caddr_t)&tp->t_outq, TTOPRI);
 719:         }
 720:         spl0();
 721:         if ((c = cpass()) < 0)
 722:             break;
 723:         ttyoutput(c, tp);
 724:     }
 725:     ttstart(tp);
 726:     return(NULL);
 727: }

Defined functions

canon defined in line 333; used 1 times
flushtty defined in line 305; used 10 times
gtty defined in line 119; used 2 times
ioctl defined in line 131; used 4 times
stty defined in line 112; used 2 times
ttioccomm defined in line 167; used 2 times
ttread defined in line 687; used 5 times
ttrstrt defined in line 658; used 6 times
ttstart defined in line 672; used 12 times
ttwrite defined in line 703; used 5 times
ttyblock defined in line 501; used 2 times
ttychars defined in line 84; used 3 times
ttyclose defined in line 100; used 4 times
ttyinput defined in line 430; used 6 times
ttyopen defined in line 61; used 5 times
ttyoutput defined in line 526; used 6 times
ttyrend defined in line 401; never used
wflushtty defined in line 288; used 3 times

Defined variables

maptab defined in line 27; used 1 times
partab defined in line 17; used 1 times

Defined struct's

a defined in line 135; used 2 times
  • in line 143(2)

Defined macros

q1 defined in line 50; used 2 times
q2 defined in line 51; used 1 times
q3 defined in line 52; never used
q4 defined in line 53; never used
Last modified: 1979-05-12
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1581
Valid CSS Valid XHTML 1.0 Strict