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
Defined variables
Defined macros