1: /*
   2:  *	SCCS id	@(#)ttyold.c	2.1 (Berkeley)	8/5/83
   3:  */
   4: 
   5: /*
   6:  * general TTY subroutines
   7:  */
   8: #include "param.h"
   9: #ifdef  OLDTTY
  10: #include <sys/systm.h>
  11: #include <sys/dir.h>
  12: #include <sys/user.h>
  13: #include <sys/tty.h>
  14: #include <sys/proc.h>
  15: #ifdef  MPX_FILS
  16: #include <sys/mx.h>
  17: #endif
  18: #include <sys/inode.h>
  19: #include <sys/file.h>
  20: #include <sys/reg.h>
  21: #include <sys/conf.h>
  22: #include <sys/buf.h>
  23: 
  24: extern  char    partab[];
  25: char    canonb[CANBSIZ];    /* buffer for erase and kill (#@) */
  26: 
  27: extern  char    maptab[];   /* see tty.c */
  28: 
  29: #define OBUFSIZ 100
  30: 
  31: 
  32: /*
  33:  * transfer raw input list to canonical list,
  34:  * doing erase-kill processing and handling escapes.
  35:  * It waits until a full line has been typed in cooked mode,
  36:  * or until any character has been typed in raw mode.
  37:  */
  38: canon(tp)
  39: register struct tty *tp;
  40: {
  41:     register char *bp;
  42:     char *bp1;
  43:     register int c;
  44:     int mc;
  45:     int s;
  46: 
  47:     if ((tp->t_flags&(RAW|CBREAK))==0 && tp->t_delct==0
  48:         || (tp->t_flags&(RAW|CBREAK))!=0 && tp->t_rawq.c_cc==0) {
  49:         return(-1);
  50:     }
  51:     s = spl0();
  52: loop:
  53:     bp = &canonb[2];
  54:     while ((c=getc(&tp->t_rawq)) >= 0) {
  55:         if ((tp->t_flags&(RAW|CBREAK))==0) {
  56:             if (c==0377) {
  57:                 tp->t_delct--;
  58:                 break;
  59:             }
  60:             if (bp[-1]!='\\') {
  61:                 if (c==tp->t_erase) {
  62:                     if (bp > &canonb[2])
  63:                         bp--;
  64:                     continue;
  65:                 }
  66:                 if (c==tp->t_kill)
  67:                     goto loop;
  68:                 if (c==tun.t_eofc)
  69:                     continue;
  70:             } else {
  71:                 if (c==tp->t_erase || c==tp->t_kill)
  72:                     mc = c;
  73:                 else
  74:                     mc = maptab[c];
  75:                 if (mc && (mc==c || (tp->t_flags&LCASE))) {
  76:                     if (bp[-2] != '\\')
  77:                         c = mc;
  78:                     bp--;
  79:                 }
  80:             }
  81:         }
  82:         *bp++ = c;
  83:         if (bp>=canonb+CANBSIZ)
  84:             break;
  85:     }
  86:     bp1 = &canonb[2];
  87:     (void) b_to_q(bp1, bp-bp1, &tp->t_canq);
  88: 
  89: 
  90:     /* Unblock output iff:
  91:  	 * is blocked
  92:  	 * AND (input < threshold OR (cooked mode AND delim_count == 0))
  93:  	 * This makes tandem mode usable for line-mode input.
  94:  	 */
  95:     if (tp->t_state&TBLOCK && ((tp->t_rawq.c_cc < TTYHOG/5) ||
  96:        (tp->t_delct==0 && ((tp->t_flags&(CBREAK|RAW)) == 0)))) {
  97:         if (putc(tun.t_startc, &tp->t_outq)==0) {
  98:             tp->t_state &= ~TBLOCK;
  99:             ttstart(tp);
 100:         }
 101:     }
 102: 
 103:     splx(s);
 104:     return(0);
 105: }
 106: 
 107: /*
 108:  * Place a character on raw TTY input queue, putting in delimiters
 109:  * and waking up top half as needed.
 110:  * Also echo if required.
 111:  * The arguments are the character and the appropriate
 112:  * tty structure.
 113:  */
 114: ttyinput(c, tp)
 115: register c;
 116: register struct tty *tp;
 117: {
 118:     register int t_flags;
 119: #ifdef  MPX_FILS
 120:     struct chan *cp;
 121: #endif
 122: 
 123:     tk_nin += 1;
 124:     c &= 0377;
 125:     t_flags = tp->t_flags;
 126:     if (t_flags&TANDEM)
 127:         ttyblock(tp);
 128:     if ((t_flags&RAW)==0) {
 129:         c &= 0177;
 130:         if (tp->t_state&TTSTOP) {
 131:             if (c==tun.t_startc) {
 132:                 tp->t_state &= ~TTSTOP;
 133:                 ttstart(tp);
 134:                 return;
 135:             }
 136:             if (c==tun.t_stopc)
 137:                 return;
 138:             tp->t_state &= ~TTSTOP;
 139:             ttstart(tp);
 140:         } else {
 141:             if (c==tun.t_stopc) {
 142:                 tp->t_state |= TTSTOP;
 143:                 (*cdevsw[major(tp->t_dev)].d_stop)(tp,0);
 144:                 return;
 145:             }
 146:             if (c==tun.t_startc)
 147:                 return;
 148:         }
 149:         if (c==tun.t_quitc || c==tun.t_intrc) {
 150:             if ((tp->t_local & LNOFLSH) == 0)
 151:                 flushtty(tp, FREAD|FWRITE);
 152:             c = (c==tun.t_intrc) ? SIGINT:SIGQUIT;
 153: #ifdef  MPX_FILS
 154:             if (tp->t_chan)
 155:                 scontrol(tp->t_chan, M_SIG, c);
 156:             else
 157: #endif
 158:                 gsignal(tp->t_pgrp, c);
 159:             return;
 160:         }
 161:         if (c=='\r' && t_flags&CRMOD)
 162:             c = '\n';
 163:     }
 164:     if (tp->t_rawq.c_cc>TTYHOG) {
 165:         flushtty(tp, FREAD|FWRITE);
 166:         return;
 167:     }
 168:     if (t_flags&LCASE && c>='A' && c<='Z')
 169:         c += 'a'-'A';
 170:     (void) putc(c, &tp->t_rawq);
 171:     if (t_flags&(RAW|CBREAK)||(c=='\n'||c==tun.t_eofc||c==tun.t_brkc)) {
 172:         if ((t_flags&(RAW|CBREAK))==0 && putc(0377, &tp->t_rawq)==0)
 173:             tp->t_delct++;
 174: #ifdef  MPX_FILS
 175:         if ((cp=tp->t_chan)!=NULL)
 176:             (void) sdata(cp);
 177:         else
 178: #endif
 179:             wakeup((caddr_t)&tp->t_rawq);
 180:     }
 181:     if (t_flags&ECHO) {
 182:         ttyoutput(c, tp);
 183:         if (c==tp->t_kill && (t_flags&(RAW|CBREAK))==0)
 184:             ttyoutput('\n', tp);
 185:         ttstart(tp);
 186:     }
 187: }
 188: 
 189: /*
 190:  * put character on TTY output queue, adding delays,
 191:  * expanding tabs, and handling the CR/NL bit.
 192:  * It is called both from the top half for output, and from
 193:  * interrupt level for echoing.
 194:  * The arguments are the character and the tty structure.
 195:  */
 196: ttyoutput(c, tp)
 197: register c;
 198: register struct tty *tp;
 199: {
 200:     register char *colp;
 201:     int ctype;
 202: 
 203:     /*
 204: 	 * Ignore EOT in normal mode to avoid hanging up
 205: 	 * certain terminals.
 206: 	 * In raw mode dump the char unchanged.
 207: 	 */
 208:     if ((tp->t_flags&RAW)==0) {
 209:         c &= 0177;
 210:         if ((tp->t_flags&CBREAK)==0 && c==CEOT)
 211:             return;
 212:     } else {
 213:         tk_nout++;
 214:         (void) putc(c, &tp->t_outq);
 215:         return;
 216:     }
 217: 
 218:     /*
 219: 	 * Turn tabs to spaces as required
 220: 	 */
 221:     if (c=='\t' && (tp->t_flags&TBDELAY)==XTABS) {
 222:         c = 8 - (tp->t_col & 7);
 223:         (void) b_to_q("        ", c, &tp->t_outq);
 224:         tp->t_col += c;
 225:         tk_nout += c;
 226:         return;
 227:     }
 228:     tk_nout++;
 229:     /*
 230: 	 * for upper-case-only terminals,
 231: 	 * generate escapes.
 232: 	 */
 233:     if (tp->t_flags&LCASE) {
 234:         colp = "({)}!|^~'`";
 235:         while(*colp++)
 236:             if(c == *colp++) {
 237:                 ttyoutput('\\', tp);
 238:                 c = colp[-2];
 239:                 break;
 240:             }
 241:         if ('a'<=c && c<='z')
 242:             c += 'A' - 'a';
 243:     }
 244:     /*
 245: 	 * turn <nl> to <cr><lf> if desired.
 246: 	 */
 247:     if (c=='\n' && tp->t_flags&CRMOD)
 248:         ttyoutput('\r', tp);
 249:     (void) putc(c, &tp->t_outq);
 250:     /*
 251: 	 * Calculate delays.
 252: 	 * The numbers here represent clock ticks
 253: 	 * and are not necessarily optimal for all terminals.
 254: 	 * The delays are indicated by characters above 0200.
 255: 	 * In raw mode there are no delays and the
 256: 	 * transmission path is 8 bits wide.
 257: 	 */
 258:     colp = &tp->t_col;
 259:     ctype = partab[c];
 260:     c = 0;
 261:     switch (ctype&077) {
 262: 
 263:     case ORDINARY:
 264:         (*colp)++;
 265: 
 266:     case CONTROL:
 267:         break;
 268: 
 269:     case BACKSPACE:
 270:         if (*colp)
 271:             (*colp)--;
 272:         break;
 273: 
 274:     case NEWLINE:
 275:         ctype = (tp->t_flags >> 8) & 03;
 276:         if(ctype == 1) { /* tty 37 */
 277:             if (*colp)
 278:                 c = MAX(((unsigned)*colp>>4) + 3, (unsigned)6);
 279:         } else
 280:         if(ctype == 2) { /* vt05 */
 281:             c = 6;
 282:         }
 283:         *colp = 0;
 284:         break;
 285: 
 286:     case TAB:
 287:         ctype = (tp->t_flags >> 10) & 03;
 288:         if(ctype == 1) { /* tty 37 */
 289:             c = 1 - (*colp | ~07);
 290:             if(c < 5)
 291:                 c = 0;
 292:         }
 293:         *colp |= 07;
 294:         (*colp)++;
 295:         break;
 296: 
 297:     case VTAB:
 298:         if(tp->t_flags & VTDELAY) /* tty 37 */
 299:             c = 0177;
 300:         break;
 301: 
 302:     case RETURN:
 303:         ctype = (tp->t_flags >> 12) & 03;
 304:         if(ctype == 1) { /* tn 300 */
 305:             c = 5;
 306:         } else if(ctype == 2) { /* ti 700 */
 307:             c = 10;
 308:         } else if(ctype == 3) { /* concept 100 */
 309:             int i;
 310:             if ((i = *colp) >= 0)
 311:                 for (; i<9; i++)
 312:                     (void) putc(0177, &tp->t_outq);
 313:         }
 314:         *colp = 0;
 315:     }
 316:     if(c)
 317:         (void) putc(c|0200, &tp->t_outq);
 318: }
 319: 
 320: /*
 321:  * Called from device's read routine after it has
 322:  * calculated the tty-structure given as argument.
 323:  */
 324: ttread(tp)
 325: register struct tty *tp;
 326: {
 327: register s;
 328: 
 329:     if ((tp->t_state&CARR_ON)==0)
 330:         return(-1);
 331:     s = spl5();
 332:     if (tp->t_canq.c_cc==0) {
 333:         while ((canon(tp)<0) && (tp->t_state&CARR_ON)) {
 334:             if ((tp->t_state&CARR_ON)==0 ||
 335: #ifdef  MPX_FILS
 336:                 (tp->t_chan!=NULL) ||
 337: #endif
 338: #ifdef  UCB_NET
 339:                 (tp->t_state&TS_NBIO)
 340: #endif
 341:                 ) {
 342:                 splx(s);
 343:                 return(0);
 344:             }
 345:             sleep((caddr_t)&tp->t_rawq, TTIPRI);
 346:         }
 347:     }
 348:     splx(s);
 349:     while (tp->t_canq.c_cc && passc(getc(&tp->t_canq))>=0)
 350:             ;
 351:     return(tp->t_rawq.c_cc+tp->t_canq.c_cc);
 352: }
 353: 
 354: /*
 355:  * Called from the device's write routine after it has
 356:  * calculated the tty-structure given as argument.
 357:  */
 358: caddr_t
 359: ttwrite(tp)
 360: register struct tty *tp;
 361: {
 362:     register char *cp;
 363:     register int ce;
 364:     int cc, i;
 365:     char obuf[OBUFSIZ];
 366:     int hiwat = TTHIWAT(tp);
 367: 
 368:     if ((tp->t_state&CARR_ON)==0)
 369:         return(NULL);
 370:     while (u.u_count) {
 371:         cc = MIN(u.u_count, OBUFSIZ);
 372:         cp = obuf;
 373:         iomove(cp, (unsigned)cc, B_WRITE);
 374:         if (u.u_error)
 375:             break;
 376:         (void) _spl5();
 377:         while (tp->t_outq.c_cc > hiwat) {
 378:             ttstart(tp);
 379: #ifdef  UCB_NET
 380:             if (tp->t_state&TS_NBIO) {
 381:                 u.u_error = EWOULDBLOCK;
 382:                 return(NULL);
 383:             }
 384: #endif
 385:             tp->t_state |= ASLEEP;
 386: #ifdef  MPX_FILS
 387:             if (tp->t_chan) {
 388:                 u.u_base -= cc;
 389:                 u.u_offset -= cc;
 390:                 u.u_count += cc;
 391:                 (void) _spl0();
 392:                 return((caddr_t)&tp->t_outq);
 393:             }
 394: #endif
 395:             sleep((caddr_t)&tp->t_outq, TTOPRI);
 396:         }
 397:         (void) _spl0();
 398:         if (tp->t_flags&LCASE) {
 399:             while (cc--)
 400:                 ttyoutput(*cp++,tp);
 401:             continue;
 402:         }
 403:         while (cc) {
 404:             if (tp->t_flags&RAW)
 405:                 ce=cc;
 406:             else {
 407:                 ce=0;
 408:                 while(((partab[(*(cp+ce))&0177]&077)==0)&&(ce<cc))
 409:                     ce++;
 410:                 if (ce==0) {
 411:                     ttyoutput(*cp++,tp);
 412:                     cc--;
 413:                     goto check;
 414:                 }
 415:             }
 416:             i=b_to_q(cp,ce,&tp->t_outq);
 417:             ce-=i;
 418:             tk_nout+=ce;
 419:             tp->t_col+=ce;
 420:             cp+=ce;
 421:             cc-=ce;
 422: check:
 423:             if (tp->t_outq.c_cc > hiwat) {
 424:                 (void) _spl5();
 425:                 while (tp->t_outq.c_cc > hiwat) {
 426:                     ttstart(tp);
 427: #ifdef  UCB_NET
 428:                     if (tp->t_state&TS_NBIO) {
 429:                         u.u_error = EWOULDBLOCK;
 430:                         return(NULL);
 431:                     }
 432: #endif
 433:                     tp->t_state |= ASLEEP;
 434:                     sleep((caddr_t)&tp->t_outq, TTOPRI);
 435:                 }
 436:                 (void) _spl0();
 437:             }
 438:         }
 439:     }
 440:     ttstart(tp);
 441:     return(NULL);
 442: }
 443: 
 444: #endif	OLDTTY

Defined functions

canon defined in line 38; used 3 times
ttread defined in line 324; never used
ttwrite defined in line 358; never used
ttyinput defined in line 114; never used
ttyoutput defined in line 196; used 6 times

Defined variables

canonb defined in line 25; used 4 times

Defined macros

OBUFSIZ defined in line 29; used 2 times
Last modified: 1983-08-06
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1270
Valid CSS Valid XHTML 1.0 Strict