xref: /csrg-svn/sys/kern/tty.c (revision 7502)
1 /*	tty.c	4.24	82/07/24	*/
2 
3 /*
4  * TTY subroutines common to more than one line discipline
5  */
6 #include "../h/param.h"
7 #include "../h/systm.h"
8 #include "../h/dir.h"
9 #include "../h/user.h"
10 #include "../h/tty.h"
11 #include "../h/proc.h"
12 #include "../h/inode.h"
13 #include "../h/file.h"
14 #include "../h/reg.h"
15 #include "../h/conf.h"
16 #include "../h/buf.h"
17 #include "../h/dk.h"
18 
19 /*
20  * Table giving parity for characters and indicating
21  * character classes to tty driver.  In particular,
22  * if the low 6 bits are 0, then the character needs
23  * no special processing on output.
24  */
25 
26 char partab[] = {
27 	0001,0201,0201,0001,0201,0001,0001,0201,
28 	0202,0004,0003,0201,0005,0206,0201,0001,
29 	0201,0001,0001,0201,0001,0201,0201,0001,
30 	0001,0201,0201,0001,0201,0001,0001,0201,
31 	0200,0000,0000,0200,0000,0200,0200,0000,
32 	0000,0200,0200,0000,0200,0000,0000,0200,
33 	0000,0200,0200,0000,0200,0000,0000,0200,
34 	0200,0000,0000,0200,0000,0200,0200,0000,
35 	0200,0000,0000,0200,0000,0200,0200,0000,
36 	0000,0200,0200,0000,0200,0000,0000,0200,
37 	0000,0200,0200,0000,0200,0000,0000,0200,
38 	0200,0000,0000,0200,0000,0200,0200,0000,
39 	0000,0200,0200,0000,0200,0000,0000,0200,
40 	0200,0000,0000,0200,0000,0200,0200,0000,
41 	0200,0000,0000,0200,0000,0200,0200,0000,
42 	0000,0200,0200,0000,0200,0000,0000,0201,
43 
44 	/*
45 	 * 7 bit ascii ends with the last character above,
46 	 * but we contine through all 256 codes for the sake
47 	 * of the tty output routines which use special vax
48 	 * instructions which need a 256 character trt table.
49 	 */
50 
51 	0007,0007,0007,0007,0007,0007,0007,0007,
52 	0007,0007,0007,0007,0007,0007,0007,0007,
53 	0007,0007,0007,0007,0007,0007,0007,0007,
54 	0007,0007,0007,0007,0007,0007,0007,0007,
55 	0007,0007,0007,0007,0007,0007,0007,0007,
56 	0007,0007,0007,0007,0007,0007,0007,0007,
57 	0007,0007,0007,0007,0007,0007,0007,0007,
58 	0007,0007,0007,0007,0007,0007,0007,0007,
59 	0007,0007,0007,0007,0007,0007,0007,0007,
60 	0007,0007,0007,0007,0007,0007,0007,0007,
61 	0007,0007,0007,0007,0007,0007,0007,0007,
62 	0007,0007,0007,0007,0007,0007,0007,0007,
63 	0007,0007,0007,0007,0007,0007,0007,0007,
64 	0007,0007,0007,0007,0007,0007,0007,0007,
65 	0007,0007,0007,0007,0007,0007,0007,0007,
66 	0007,0007,0007,0007,0007,0007,0007,0007
67 };
68 
69 /*
70  * Input mapping table-- if an entry is non-zero, when the
71  * corresponding character is typed preceded by "\" the escape
72  * sequence is replaced by the table value.  Mostly used for
73  * upper-case only terminals.
74  */
75 
76 char	maptab[] ={
77 	000,000,000,000,000,000,000,000,
78 	000,000,000,000,000,000,000,000,
79 	000,000,000,000,000,000,000,000,
80 	000,000,000,000,000,000,000,000,
81 	000,'|',000,000,000,000,000,'`',
82 	'{','}',000,000,000,000,000,000,
83 	000,000,000,000,000,000,000,000,
84 	000,000,000,000,000,000,000,000,
85 	000,000,000,000,000,000,000,000,
86 	000,000,000,000,000,000,000,000,
87 	000,000,000,000,000,000,000,000,
88 	000,000,000,000,000,000,'~',000,
89 	000,'A','B','C','D','E','F','G',
90 	'H','I','J','K','L','M','N','O',
91 	'P','Q','R','S','T','U','V','W',
92 	'X','Y','Z',000,000,000,000,000,
93 };
94 
95 short	tthiwat[16] =
96    { 100,100,100,100,100,100,100,200,200,400,400,400,650,650,650,650 };
97 short	ttlowat[16] =
98    {  30, 30, 30, 30, 30, 30, 30, 50, 50,120,120,120,125,125,125,125 };
99 
100 #define	OBUFSIZ	100
101 
102 /*
103  * set default control characters.
104  */
105 ttychars(tp)
106 register struct tty *tp;
107 {
108 
109 	tun.t_intrc = CINTR;
110 	tun.t_quitc = CQUIT;
111 	tun.t_startc = CSTART;
112 	tun.t_stopc = CSTOP;
113 	tun.t_eofc = CEOT;
114 	tun.t_brkc = CBRK;
115 	tp->t_erase = CERASE;
116 	tp->t_kill = CKILL;
117 /* begin local */
118 	tlun.t_suspc = CTRL(z);
119 	tlun.t_dsuspc = CTRL(y);
120 	tlun.t_rprntc = CTRL(r);
121 	tlun.t_flushc = CTRL(o);
122 	tlun.t_werasc = CTRL(w);
123 	tlun.t_lnextc = CTRL(v);
124 	tp->t_local = 0;
125 	tp->t_lstate = 0;
126 /* end local */
127 }
128 
129 /*
130  * Wait for output to drain, then flush input waiting.
131  */
132 wflushtty(tp)
133 	register struct tty *tp;
134 {
135 
136 	(void) spl5();
137 	while (tp->t_outq.c_cc && tp->t_state&TS_CARR_ON
138 	    && tp->t_oproc) {		/* kludge for pty */
139 		(*tp->t_oproc)(tp);
140 		tp->t_state |= TS_ASLEEP;
141 		sleep((caddr_t)&tp->t_outq, TTOPRI);
142 	}
143 	flushtty(tp, FREAD);
144 	(void) spl0();
145 }
146 
147 /*
148  * flush all TTY queues
149  */
150 flushtty(tp, rw)
151 register struct tty *tp;
152 {
153 	register s;
154 
155 	s = spl6();
156 	if (rw & FREAD) {
157 		while (getc(&tp->t_canq) >= 0)
158 			;
159 		wakeup((caddr_t)&tp->t_rawq);
160 	}
161 	if (rw & FWRITE) {
162 		wakeup((caddr_t)&tp->t_outq);
163 		tp->t_state &= ~TS_TTSTOP;
164 		(*cdevsw[major(tp->t_dev)].d_stop)(tp, rw);
165 		while (getc(&tp->t_outq) >= 0)
166 			;
167 	}
168 	if (rw & FREAD) {
169 		while (getc(&tp->t_rawq) >= 0)
170 			;
171 		tp->t_delct = 0;
172 		tp->t_rocount = 0;		/* local */
173 		tp->t_rocol = 0;
174 		tp->t_lstate = 0;
175 	}
176 	splx(s);
177 }
178 
179 /*
180  * Send stop character on input overflow.
181  */
182 ttyblock(tp)
183 register struct tty *tp;
184 {
185 	register x;
186 	x = tp->t_rawq.c_cc + tp->t_canq.c_cc;
187 	if (tp->t_rawq.c_cc > TTYHOG) {
188 		flushtty(tp, FREAD|FWRITE);
189 		tp->t_state &= ~TS_TBLOCK;
190 	}
191 	if (x >= TTYHOG/2) {
192 		if (putc(tun.t_stopc, &tp->t_outq)==0) {
193 			tp->t_state |= TS_TBLOCK;
194 			tp->t_char++;
195 			ttstart(tp);
196 		}
197 	}
198 }
199 
200 /*
201  * Restart typewriter output following a delay
202  * timeout.
203  * The name of the routine is passed to the timeout
204  * subroutine and it is called during a clock interrupt.
205  */
206 ttrstrt(tp)
207 register struct tty *tp;
208 {
209 
210 	if (tp == 0) {
211 		printf("ttrstrt: arg was 0!\n");
212 		return;
213 	}
214 	tp->t_state &= ~TS_TIMEOUT;
215 	ttstart(tp);
216 }
217 
218 /*
219  * Start output on the typewriter. It is used from the top half
220  * after some characters have been put on the output queue,
221  * from the interrupt routine to transmit the next
222  * character, and after a timeout has finished.
223  */
224 ttstart(tp)
225 register struct tty *tp;
226 {
227 	register s;
228 
229 	s = spl5();
230 	if((tp->t_state&(TS_TIMEOUT|TS_TTSTOP|TS_BUSY)) == 0 &&
231 	    tp->t_oproc)		/* kludge for pty */
232 		(*tp->t_oproc)(tp);
233 	splx(s);
234 }
235 
236 /*
237  * Common code for tty ioctls.
238  */
239 /*ARGSUSED*/
240 ttioctl(tp, com, addr, flag)
241 register struct tty *tp;
242 caddr_t addr;
243 {
244 	int dev;
245 	unsigned t;
246 	struct sgttyb iocb;
247 	struct clist tq;
248 	extern int nldisp;
249 	register c;
250 	int temp;
251 
252 	/*
253 	 * This is especially so that isatty() will
254 	 * fail when carrier is gone.
255 	 */
256 	if ((tp->t_state&TS_CARR_ON) == 0) {
257 		u.u_error = EBADF;
258 		return (1);
259 	}
260 
261 	dev = tp->t_dev;
262 	/*
263 	 * If the ioctl involves modification,
264 	 * insist on being able to write the device,
265 	 * and hang if in the background.
266 	 */
267 	switch(com) {
268 
269 	case TIOCSETD:
270 	case TIOCSETP:
271 	case TIOCSETN:
272 	case TIOCFLUSH:
273 	case TIOCSETC:
274 	case TIOCSLTC:
275 	case TIOCSPGRP:
276 	case TIOCLBIS:
277 	case TIOCLBIC:
278 	case TIOCLSET:
279 	case TIOCSTI:
280 /* this is reasonable, but impractical...
281 		if ((flag & FWRITE) == 0) {
282 			u.u_error = EBADF;
283 			return (1);
284 		}
285  */
286 		while (tp->t_line == NTTYDISC &&
287 		   u.u_procp->p_pgrp != tp->t_pgrp && tp == u.u_ttyp &&
288 		   (u.u_procp->p_flag&SVFORK) == 0 &&
289 		   u.u_signal[SIGTTOU] != SIG_IGN &&
290 		   u.u_signal[SIGTTOU] != SIG_HOLD
291 /*
292 						   &&
293 		   (u.u_procp->p_flag&SDETACH)==0) {
294 */
295 		   ) {
296 			gsignal(u.u_procp->p_pgrp, SIGTTOU);
297 			sleep((caddr_t)&lbolt, TTOPRI);
298 		}
299 		break;
300 	}
301 
302 	/*
303 	 * Process the ioctl.
304 	 */
305 	switch(com) {
306 
307 	/*
308 	 * Get discipline number
309 	 */
310 	case TIOCGETD:
311 		t = tp->t_line;
312 		if (copyout((caddr_t)&t, addr, sizeof(t)))
313 			u.u_error = EFAULT;
314 		break;
315 
316 	/*
317 	 * Set line discipline
318 	 */
319 	case TIOCSETD:
320 		if (copyin(addr, (caddr_t)&t, sizeof(t))) {
321 			u.u_error = EFAULT;
322 			break;
323 		}
324 		if (t >= nldisp) {
325 			u.u_error = ENXIO;
326 			break;
327 		}
328 		(void) spl5();
329 		if (tp->t_line)
330 			(*linesw[tp->t_line].l_close)(tp);
331 		if (t)
332 			(*linesw[t].l_open)(dev, tp, addr);
333 		if (u.u_error==0)
334 			tp->t_line = t;
335 		(void) spl0();
336 		break;
337 
338 	/*
339 	 * Prevent more opens on channel
340 	 */
341 	case TIOCEXCL:
342 		tp->t_state |= TS_XCLUDE;
343 		break;
344 
345 	case TIOCNXCL:
346 		tp->t_state &= ~TS_XCLUDE;
347 		break;
348 
349 	/*
350 	 * Set new parameters
351 	 */
352 	case TIOCSETP:
353 	case TIOCSETN:
354 		if (copyin(addr, (caddr_t)&iocb, sizeof(iocb))) {
355 			u.u_error = EFAULT;
356 			return(1);
357 		}
358 		(void) spl5();
359 		if (tp->t_flags&RAW || iocb.sg_flags&RAW ||
360 		    com == TIOCSETP)
361 			wflushtty(tp);
362 		else if ((tp->t_flags&CBREAK) != (iocb.sg_flags&CBREAK)) {
363 			if (iocb.sg_flags & CBREAK) {
364 				catq(&tp->t_rawq, &tp->t_canq);
365 				tq = tp->t_rawq;
366 				tp->t_rawq = tp->t_canq;
367 				tp->t_canq = tq;
368 			} else {
369 				tp->t_local |= LPENDIN;
370 				ttwakeup(tp);
371 			}
372 		}
373 		tp->t_ispeed = iocb.sg_ispeed;
374 		tp->t_ospeed = iocb.sg_ospeed;
375 		tp->t_erase = iocb.sg_erase;
376 		tp->t_kill = iocb.sg_kill;
377 		tp->t_flags = iocb.sg_flags;
378 		if (tp->t_flags & RAW) {
379 			tp->t_state &= ~TS_TTSTOP;
380 			ttstart(tp);
381 		}
382 		(void) spl0();
383 		break;
384 
385 	/*
386 	 * Send current parameters to user
387 	 */
388 	case TIOCGETP:
389 		iocb.sg_ispeed = tp->t_ispeed;
390 		iocb.sg_ospeed = tp->t_ospeed;
391 		iocb.sg_erase = tp->t_erase;
392 		iocb.sg_kill = tp->t_kill;
393 		iocb.sg_flags = tp->t_flags;
394 		if (copyout((caddr_t)&iocb, addr, sizeof(iocb)))
395 			u.u_error = EFAULT;
396 		break;
397 
398 	/*
399 	 * Hang up line on last close
400 	 */
401 	case TIOCHPCL:
402 		tp->t_state |= TS_HUPCLS;
403 		break;
404 
405 	case TIOCFLUSH: {
406 		int flags;
407 		if (addr == 0)
408 			flags = FREAD|FWRITE;
409 		else if (copyin(addr, (caddr_t)&flags, sizeof (flags))) {
410 			u.u_error = EFAULT;
411 			return(1);
412 		}
413 		flushtty(tp, flags);
414 		break;
415 	}
416 
417 	case FIONBIO: {
418 		int nbio;
419 		if (copyin(addr, (caddr_t)&nbio, sizeof (nbio))) {
420 			u.u_error = EFAULT;
421 			return(1);
422 		}
423 		if (nbio)
424 			tp->t_state |= TS_NBIO;
425 		else
426 			tp->t_state &= ~TS_NBIO;
427 		break;
428 	}
429 
430 	case FIOASYNC: {
431 		int async;
432 		if (copyin(addr, (caddr_t)&async, sizeof (async))) {
433 			u.u_error = EFAULT;
434 			return(1);
435 		}
436 		if (async)
437 			tp->t_state |= TS_ASYNC;
438 		else
439 			tp->t_state &= ~TS_ASYNC;
440 		break;
441 	}
442 
443 	/*
444 	 * Set and fetch special characters
445 	 */
446 	case TIOCSETC:
447 		if (copyin(addr, (caddr_t)&tun, sizeof(struct tchars)))
448 			u.u_error = EFAULT;
449 		break;
450 
451 	case TIOCGETC:
452 		if (copyout((caddr_t)&tun, addr, sizeof(struct tchars)))
453 			u.u_error = EFAULT;
454 		break;
455 
456 /* local ioctls */
457 	/*
458 	 * Set/get local special characters.
459 	 */
460 	case TIOCSLTC:
461 		if (copyin(addr, (caddr_t)&tlun, sizeof (struct ltchars)))
462 			u.u_error = EFAULT;
463 		break;
464 
465 	case TIOCGLTC:
466 		if (copyout((caddr_t)&tlun, addr, sizeof (struct ltchars)))
467 			u.u_error = EFAULT;
468 		break;
469 
470 	/*
471 	 * Return number of characters immediately available.
472 	 */
473 	case FIONREAD: {
474 		off_t nread = ttnread(tp);
475 		if (copyout((caddr_t)&nread, addr, sizeof (off_t)))
476 			u.u_error = EFAULT;
477 		break;
478 		}
479 
480 	/*
481 	 * Should allow SPGRP and GPGRP only if tty open for reading.
482 	 */
483 	case TIOCSPGRP:
484 		if (copyin(addr, (caddr_t)&tp->t_pgrp, sizeof (tp->t_pgrp)))
485 			u.u_error = EFAULT;
486 		break;
487 
488 	case TIOCGPGRP:
489 		if (copyout((caddr_t)&tp->t_pgrp, addr, sizeof(tp->t_pgrp)))
490 			u.u_error = EFAULT;
491 		break;
492 
493 	/*
494 	 * Modify local mode word.
495 	 */
496 	case TIOCLBIS:
497 		if (copyin(addr, (caddr_t)&temp, sizeof (tp->t_local)))
498 			u.u_error = EFAULT;
499 		else
500 			tp->t_local |= temp;
501 		break;
502 
503 	case TIOCLBIC:
504 		if (copyin(addr, (caddr_t)&temp, sizeof (tp->t_local)))
505 			u.u_error = EFAULT;
506 		else
507 			tp->t_local &= ~temp;
508 		break;
509 
510 	case TIOCLSET:
511 		if (copyin(addr, (caddr_t)&temp, sizeof (tp->t_local)))
512 			u.u_error = EFAULT;
513 		else
514 			tp->t_local = temp;
515 		break;
516 
517 	case TIOCLGET:
518 		if (copyout((caddr_t)&tp->t_local, addr, sizeof(tp->t_local)))
519 			u.u_error = EFAULT;
520 		break;
521 
522 	/*
523 	 * Return number of characters in
524 	 * the output.
525 	 */
526 	case TIOCOUTQ:
527 		if (copyout((caddr_t)&tp->t_outq.c_cc, addr, sizeof(tp->t_outq.c_cc)))
528 			u.u_error = EFAULT;
529 		break;
530 
531 	/*
532 	 * Simulate typing of a character at the terminal.
533 	 */
534 	case TIOCSTI:
535 		c = fubyte(addr);
536 		if (u.u_uid && u.u_ttyp != tp || c < 0)
537 			u.u_error = EFAULT;
538 		else
539 			(*linesw[tp->t_line].l_rint)(c, tp);
540 		break;
541 
542 	case TIOCSTOP:
543 		c = spl5();
544 		if ((tp->t_state & TS_TTSTOP) == 0) {
545 			tp->t_state |= TS_TTSTOP;
546 			(*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
547 		}
548 		splx(c);
549 		break;
550 
551 	case TIOCSTART:
552 		c = spl5();
553 		if ((tp->t_state & TS_TTSTOP) || (tp->t_local & LFLUSHO)) {
554 			tp->t_state &= ~TS_TTSTOP;
555 			tp->t_local &= ~LFLUSHO;
556 			ttstart(tp);
557 		}
558 		splx(c);
559 		break;
560 
561 /* end of locals */
562 
563 	default:
564 		return(0);
565 	}
566 	return(1);
567 }
568 
569 ttnread(tp)
570 	struct tty *tp;
571 {
572 	int nread = 0;
573 
574 	if (tp->t_local & LPENDIN)
575 		ttypend(tp);
576 	nread = tp->t_canq.c_cc;
577 	if (tp->t_flags & (RAW|CBREAK))
578 		nread += tp->t_rawq.c_cc;
579 	return (nread);
580 }
581 
582 ttselect(dev, rw)
583 	dev_t dev;
584 	int rw;
585 {
586 	register struct tty *tp = &cdevsw[major(dev)].d_ttys[minor(dev)];
587 	int nread;
588 	int s = spl5();
589 
590 	switch (rw) {
591 
592 	case FREAD:
593 		nread = ttnread(tp);
594 		if (nread > 0)
595 			goto win;
596 		if (tp->t_rsel && tp->t_rsel->p_wchan == (caddr_t)&selwait)
597 			tp->t_state |= TS_RCOLL;
598 		else
599 			tp->t_rsel = u.u_procp;
600 		break;
601 
602 	case FWRITE:
603 		if (tp->t_outq.c_cc <= TTLOWAT(tp))
604 			goto win;
605 		if (tp->t_wsel && tp->t_wsel->p_wchan == (caddr_t)&selwait)
606 			tp->t_state |= TS_WCOLL;
607 		else
608 			tp->t_wsel = u.u_procp;
609 		break;
610 	}
611 	splx(s);
612 	return (0);
613 win:
614 	splx(s);
615 	return (1);
616 }
617 
618 #define	OBUFSIZ	100
619 
620 /*
621  * routine called on opens while tp->t_line == NTTYDISC
622  * establishes a process group for distribution of
623  * quits and interrupts from the tty.
624  * (actually, pp->p_pgrp can't be 0 when this routine
625  * is called since NTTYDISC is not the default discipline)
626  */
627 ttyopen(dev, tp)
628 dev_t dev;
629 register struct tty *tp;
630 {
631 	register struct proc *pp;
632 
633 	pp = u.u_procp;
634 	tp->t_dev = dev;
635 	if(pp->p_pgrp == 0) {
636 		u.u_ttyp = tp;
637 		u.u_ttyd = dev;
638 		if (tp->t_pgrp == 0)
639 			tp->t_pgrp = pp->p_pid;
640 		pp->p_pgrp = tp->t_pgrp;
641 	}
642 	tp->t_state &= ~TS_WOPEN;
643 	tp->t_state |= TS_ISOPEN;
644 	if (tp->t_line != NTTYDISC)
645 		wflushtty(tp);
646 }
647 
648 /*
649  * clean tp on last close
650  */
651 ttyclose(tp)
652 register struct tty *tp;
653 {
654 
655 	if (tp->t_line) {
656 		wflushtty(tp);
657 		tp->t_line = 0;
658 		return;
659 	}
660 	tp->t_pgrp = 0;
661 	wflushtty(tp);
662 	tp->t_state = 0;
663 }
664 
665 /*
666  * reinput pending characters after state switch
667  * call at spl5().
668  */
669 ttypend(tp)
670 register struct tty *tp;
671 {
672 	struct clist tq;
673 	register c;
674 
675 	tp->t_local &= ~LPENDIN;
676 	tp->t_lstate |= LSTYPEN;
677 	tq = tp->t_rawq;
678 	tp->t_rawq.c_cc = 0;
679 	tp->t_rawq.c_cf = tp->t_rawq.c_cl = 0;
680 	while ((c = getc(&tq)) >= 0)
681 		ttyinput(c, tp);
682 	tp->t_lstate &= ~LSTYPEN;
683 }
684 
685 /*
686  * Place a character on raw TTY input queue, putting in delimiters
687  * and waking up top half as needed.
688  * Also echo if required.
689  * The arguments are the character and the appropriate
690  * tty structure.
691  */
692 ttyinput(c, tp)
693 register c;
694 register struct tty *tp;
695 {
696 	register int t_flags;
697 	int i;
698 
699 	if (tp->t_local&LPENDIN)
700 		ttypend(tp);
701 	tk_nin++;
702 	c &= 0377;
703 	t_flags = tp->t_flags;
704 	if (t_flags&TANDEM)
705 		ttyblock(tp);
706 	if ((t_flags&RAW)==0) {
707 		if ((tp->t_lstate&LSTYPEN) == 0)
708 			c &= 0177;
709 	/* check for literal nexting very first */
710 		if (tp->t_lstate&LSLNCH) {
711 			c |= 0200;
712 			tp->t_lstate &= ~LSLNCH;
713 		}
714 		if (tp->t_line == NTTYDISC && c==tlun.t_lnextc) {
715 			if (tp->t_flags&ECHO)
716 				ttyout("^\b", tp);
717 			tp->t_lstate |= LSLNCH;
718 	/* check for output control functions */
719 		} else if (c==tun.t_stopc) {
720 			if ((tp->t_state&TS_TTSTOP)==0) {
721 				tp->t_state |= TS_TTSTOP;
722 				(*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
723 				return;
724 			}
725 			if (c!=tun.t_startc)
726 				return;
727 		} else if (c==tun.t_startc) {
728 			tp->t_state &= ~TS_TTSTOP;
729 			tp->t_local &= ~LFLUSHO;
730 			ttstart(tp);
731 			return;
732 		} else if (tp->t_line == NTTYDISC && c==tlun.t_flushc) {
733 			if (tp->t_local & LFLUSHO)
734 				tp->t_local &= ~LFLUSHO;
735 			else {
736 				flushtty(tp, FWRITE);
737 				ttyecho(c, tp);
738 				if (tp->t_rawq.c_cc+tp->t_canq.c_cc)
739 					ttyretype(tp);
740 				tp->t_local |= LFLUSHO;
741 			}
742 			ttstart(tp);
743 			return;
744 		} else if (c==tun.t_intrc || c==tun.t_quitc ||
745 		    (tp->t_line == NTTYDISC && c==tlun.t_suspc)) {
746 			if ((tp->t_local & LNOFLSH) == 0)
747 				flushtty(tp,
748 				    c==tlun.t_suspc ? FREAD : FREAD|FWRITE);
749 			ttyecho(c, tp);
750 			c = c==tun.t_intrc ? SIGINT :
751 				((c==tun.t_quitc) ? SIGQUIT : SIGTSTP);
752 			ttsignal(tp, c);
753 	/* check for buffer editing functions - cooked mode */
754 		} else if ((t_flags&CBREAK) == 0) {
755 			if ((tp->t_lstate&LSQUOT) &&
756 			    (c==tp->t_erase||c==tp->t_kill)) {
757 				ttyrub(unputc(&tp->t_rawq), tp);
758 				c |= 0200;
759 			}
760 			if (c==tp->t_erase) {
761 				if (tp->t_rawq.c_cc)
762 					ttyrub(unputc(&tp->t_rawq), tp);
763 			} else if (c==tp->t_kill) {
764 				if (tp->t_local&LCRTKIL &&
765 				    tp->t_rawq.c_cc == tp->t_rocount) {
766 					while (tp->t_rawq.c_cc)
767 						ttyrub(unputc(&tp->t_rawq), tp);
768 				} else {
769 					ttyecho(c, tp);
770 					ttyecho('\n', tp);
771 					while (getc(&tp->t_rawq) > 0)
772 						;
773 					tp->t_rocount = 0;
774 				}
775 				tp->t_lstate = 0;
776 			} else if (tp->t_line == NTTYDISC && c==tlun.t_werasc) {
777 				if (tp->t_rawq.c_cc == 0)
778 					goto out;
779 				do {
780 					c = unputc(&tp->t_rawq);
781 					if (c != ' ' && c != '\t')
782 						goto erasenb;
783 					ttyrub(c, tp);
784 				} while (tp->t_rawq.c_cc);
785 				goto out;
786 			    erasenb:
787 				do {
788 					ttyrub(c, tp);
789 					if (tp->t_rawq.c_cc == 0)
790 						goto out;
791 					c = unputc(&tp->t_rawq);
792 				} while (c != ' ' && c != '\t');
793 				(void) putc(c, &tp->t_rawq);
794 			} else if (tp->t_line == NTTYDISC && c==tlun.t_rprntc) {
795 				ttyretype(tp);
796 	/* check for cooked mode input buffer overflow */
797 			} else if (tp->t_rawq.c_cc+tp->t_canq.c_cc >= TTYHOG) {
798 				;
799 	/* put data char in q for user and wakeup if a break char */
800 			} else if (putc(c, &tp->t_rawq) >= 0) {
801 				if (tp->t_rawq.c_cc+tp->t_canq.c_cc==TTYHOG
802 				    && tp->t_line == NTTYDISC)
803 					(void) ttyoutput(CTRL(g), tp);
804 				if (!ttbreakc(c, tp)) {
805 					if (tp->t_rocount++ == 0)
806 						tp->t_rocol = tp->t_col;
807 				} else {
808 					tp->t_rocount = 0;
809 					catq(&tp->t_rawq, &tp->t_canq);
810 					/* IF (TP->T_CHAN) (VOID) SDATA(TP->T_CHAN); */
811 					ttwakeup(tp);
812 				}
813 				tp->t_lstate &= ~LSQUOT;
814 				if (c == '\\')
815 					tp->t_lstate |= LSQUOT;
816 				if (tp->t_lstate&LSERASE) {
817 					tp->t_lstate &= ~LSERASE;
818 					(void) ttyoutput('/', tp);
819 				}
820 				i = tp->t_col;
821 				ttyecho(c, tp);
822 				if (c==tun.t_eofc && tp->t_flags&ECHO) {
823 					i = MIN(2, tp->t_col - i);
824 					while (i > 0) {
825 						(void) ttyoutput('\b', tp);
826 						i--;
827 					}
828 				}
829 			}
830 	/* CBREAK mode */
831 		} else if (tp->t_rawq.c_cc > TTYHOG) {
832 			if (tp->t_outq.c_cc < TTHIWAT(tp) &&
833 			    tp->t_line == NTTYDISC)
834 				(void) ttyoutput(CTRL(g), tp);
835 		} else if (putc(c, &tp->t_rawq) >= 0) {
836 			ttwakeup(tp);
837 			ttyecho(c, tp);
838 		}
839 	/* RAW mode */
840 	} else if (tp->t_rawq.c_cc > TTYHOG)
841 		flushtty(tp, FREAD|FWRITE);
842 	else {
843 		if (putc(c, &tp->t_rawq) >= 0)
844 			ttwakeup(tp);
845 		ttyecho(c, tp);
846 	}
847 out:
848 	if (tp->t_local & LDECCTQ && tp->t_state & TS_TTSTOP &&
849 	    tun.t_startc != tun.t_stopc)
850 		return;
851 	tp->t_state &= ~TS_TTSTOP;
852 	tp->t_local &= ~LFLUSHO;
853 	ttstart(tp);
854 }
855 
856 /*
857  * put character on TTY output queue, adding delays,
858  * expanding tabs, and handling the CR/NL bit.
859  * It is called both from the top half for output, and from
860  * interrupt level for echoing.
861  * The arguments are the character and the tty structure.
862  * Returns < 0 if putc succeeds, otherwise returns char to resend
863  * Must be recursive.
864  */
865 ttyoutput(c, tp)
866 	register c;
867 	register struct tty *tp;
868 {
869 	register char *colp;
870 	register ctype;
871 
872 	if (tp->t_flags&RAW || tp->t_local&LLITOUT) {
873 		if (tp->t_local&LFLUSHO)
874 			return (-1);
875 		if (putc(c, &tp->t_outq))
876 			return(c);
877 		tk_nout++;
878 		return (-1);
879 	}
880 	/*
881 	 * Ignore EOT in normal mode to avoid hanging up
882 	 * certain terminals.
883 	 */
884 	c &= 0177;
885 	if (c==CEOT && (tp->t_flags&CBREAK)==0)
886 		return (-1);
887 	/*
888 	 * Turn tabs to spaces as required
889 	 */
890 	if (c=='\t' && (tp->t_flags&TBDELAY)==XTABS) {
891 		register int s;
892 
893 		c = 8 - (tp->t_col&7);
894 		if ((tp->t_local&LFLUSHO) == 0) {
895 			s = spl5();		/* don't interrupt tabs */
896 			c -= b_to_q("        ", c, &tp->t_outq);
897 			tk_nout += c;
898 			splx(s);
899 		}
900 		tp->t_col += c;
901 		return (c ? -1 : '\t');
902 	}
903 	tk_nout++;
904 	/*
905 	 * for upper-case-only terminals,
906 	 * generate escapes.
907 	 */
908 	if (tp->t_flags&LCASE) {
909 		colp = "({)}!|^~'`";
910 		while(*colp++)
911 			if(c == *colp++) {
912 				if (ttyoutput('\\', tp) >= 0)
913 					return (c);
914 				c = colp[-2];
915 				break;
916 			}
917 		if ('A'<=c && c<='Z') {
918 			if (ttyoutput('\\', tp) >= 0)
919 				return (c);
920 		} else if ('a'<=c && c<='z')
921 			c += 'A' - 'a';
922 	}
923 	/*
924 	 * turn <nl> to <cr><lf> if desired.
925 	 */
926 	if (c=='\n' && tp->t_flags&CRMOD)
927 		if (ttyoutput('\r', tp) >= 0)
928 			return (c);
929 	if (c=='~' && tp->t_local&LTILDE)
930 		c = '`';
931 	if ((tp->t_local&LFLUSHO) == 0 && putc(c, &tp->t_outq))
932 		return (c);
933 	/*
934 	 * Calculate delays.
935 	 * The numbers here represent clock ticks
936 	 * and are not necessarily optimal for all terminals.
937 	 * The delays are indicated by characters above 0200.
938 	 * In raw mode there are no delays and the
939 	 * transmission path is 8 bits wide.
940 	 */
941 	colp = &tp->t_col;
942 	ctype = partab[c];
943 	c = 0;
944 	switch (ctype&077) {
945 
946 	case ORDINARY:
947 		(*colp)++;
948 
949 	case CONTROL:
950 		break;
951 
952 	case BACKSPACE:
953 		if (*colp)
954 			(*colp)--;
955 		break;
956 
957 	case NEWLINE:
958 		ctype = (tp->t_flags >> 8) & 03;
959 		if(ctype == 1) { /* tty 37 */
960 			if (*colp)
961 				c = max(((unsigned)*colp>>4) + 3, (unsigned)6);
962 		} else
963 		if(ctype == 2) { /* vt05 */
964 			c = 6;
965 		}
966 		*colp = 0;
967 		break;
968 
969 	case TAB:
970 		ctype = (tp->t_flags >> 10) & 03;
971 		if(ctype == 1) { /* tty 37 */
972 			c = 1 - (*colp | ~07);
973 			if(c < 5)
974 				c = 0;
975 		}
976 		*colp |= 07;
977 		(*colp)++;
978 		break;
979 
980 	case VTAB:
981 		if(tp->t_flags & VTDELAY) /* tty 37 */
982 			c = 0177;
983 		break;
984 
985 	case RETURN:
986 		ctype = (tp->t_flags >> 12) & 03;
987 		if(ctype == 1) { /* tn 300 */
988 			c = 5;
989 		} else if(ctype == 2) { /* ti 700 */
990 			c = 10;
991 		} else if(ctype == 3) { /* concept 100 */
992 			int i;
993 			if ((i = *colp) >= 0)
994 				for (; i<9; i++)
995 					(void) putc(0177, &tp->t_outq);
996 		}
997 		*colp = 0;
998 	}
999 	if(c && (tp->t_local&LFLUSHO) == 0)
1000 		(void) putc(c|0200, &tp->t_outq);
1001 	return (-1);
1002 }
1003 
1004 /*
1005  * Called from device's read routine after it has
1006  * calculated the tty-structure given as argument.
1007  */
1008 ttread(tp)
1009 register struct tty *tp;
1010 {
1011 	register struct clist *qp;
1012 	register c, first;
1013 
1014 	if ((tp->t_state&TS_CARR_ON)==0)
1015 		return(0);
1016 loop:
1017 	(void) spl5();
1018 	if (tp->t_local&LPENDIN)
1019 		ttypend(tp);
1020 	(void) spl0();
1021 	while (tp == u.u_ttyp && u.u_procp->p_pgrp != tp->t_pgrp) {
1022 		if (u.u_signal[SIGTTIN] == SIG_IGN ||
1023 		    u.u_signal[SIGTTIN] == SIG_HOLD ||
1024 /*
1025 		    (u.u_procp->p_flag&SDETACH) ||
1026 */
1027 		    u.u_procp->p_flag&SVFORK)
1028 			return (0);
1029 		gsignal(u.u_procp->p_pgrp, SIGTTIN);
1030 		sleep((caddr_t)&lbolt, TTIPRI);
1031 	}
1032 	if (tp->t_flags&RAW) {
1033 		(void) spl5();
1034 		if (tp->t_rawq.c_cc <= 0) {
1035 			if ((tp->t_state&TS_CARR_ON)==0 ||
1036 			    (tp->t_state&TS_NBIO)) {
1037 				(void) spl0();
1038 				return (0);
1039 			}
1040 			sleep((caddr_t)&tp->t_rawq, TTIPRI);
1041 			(void) spl0();
1042 			goto loop;
1043 		}
1044 		(void) spl0();
1045 		while (tp->t_rawq.c_cc && passc(getc(&tp->t_rawq))>=0)
1046 			;
1047 		return (0);
1048 	} else {
1049 		qp = tp->t_flags & CBREAK ? &tp->t_rawq : &tp->t_canq;
1050 		(void) spl5();
1051 		if (qp->c_cc <= 0) {
1052 			if ((tp->t_state&TS_CARR_ON)==0 ||
1053 			    (tp->t_state&TS_NBIO)) {
1054 				(void) spl0();
1055 				return (0);
1056 			}
1057 			sleep((caddr_t)&tp->t_rawq, TTIPRI);
1058 			(void) spl0();
1059 			goto loop;
1060 		}
1061 		(void) spl0();
1062 		first = 1;
1063 		while ((c = getc(qp)) >= 0) {
1064 			if (tp->t_flags&CRMOD && c == '\r')
1065 				c = '\n';
1066 			if (tp->t_flags&LCASE && c <= 0177)
1067 				if (tp->t_lstate&LSBKSL) {
1068 					if (maptab[c])
1069 						c = maptab[c];
1070 					tp->t_lstate &= ~LSBKSL;
1071 				} else if (c >= 'A' && c <= 'Z')
1072 					c += 'a' - 'A';
1073 				else if (c == '\\') {
1074 					tp->t_lstate |= LSBKSL;
1075 					continue;
1076 				}
1077 			if (c == tlun.t_dsuspc) {
1078 				ttsignal(tp, SIGTSTP);
1079 				if (first) {
1080 					sleep((caddr_t)&lbolt, TTIPRI);
1081 					goto loop;
1082 				}
1083 				break;
1084 			}
1085 			if (c == tun.t_eofc && (tp->t_flags&CBREAK)==0)
1086 				break;
1087 			if (passc(c & 0177) < 0)
1088 				break;
1089 			if ((tp->t_flags&CBREAK)==0 && ttbreakc(c, tp))
1090 				break;
1091 			first = 0;
1092 		}
1093 		tp->t_lstate &= ~LSBKSL;
1094 	}
1095 
1096 	if (tp->t_state&TS_TBLOCK && tp->t_rawq.c_cc < TTYHOG/5) {
1097 		if (putc(tun.t_startc, &tp->t_outq)==0) {
1098 			tp->t_state &= ~TS_TBLOCK;
1099 			ttstart(tp);
1100 		}
1101 		tp->t_char = 0;
1102 	}
1103 
1104 	return (tp->t_rawq.c_cc + tp->t_canq.c_cc);
1105 }
1106 
1107 /*
1108  * Called from the device's write routine after it has
1109  * calculated the tty-structure given as argument.
1110  */
1111 caddr_t
1112 ttwrite(tp)
1113 register struct tty *tp;
1114 {
1115 #ifdef vax
1116 	/*
1117 	 * THE POSITIONING OF CP, CC, AND CE ARE CRITICAL
1118 	 * AND MUST NOT BE CHANGED WITHOUT PATCHING
1119 	 * THE 'ASM' INLINES BELOW.  WATCH OUT.
1120 	 */
1121 #endif
1122 	register char *cp;
1123 	register int cc, ce;
1124 	register i;
1125 	char obuf[OBUFSIZ];
1126 	register c;
1127 	int hiwat = TTHIWAT(tp);
1128 	int cnt = u.u_count;
1129 
1130 	if ((tp->t_state&TS_CARR_ON)==0)
1131 		return (NULL);
1132 loop:
1133 	while (u.u_procp->p_pgrp != tp->t_pgrp && tp == u.u_ttyp &&
1134 	    (tp->t_local&LTOSTOP) && (u.u_procp->p_flag&SVFORK)==0 &&
1135 	    u.u_signal[SIGTTOU] != SIG_IGN &&
1136 	    u.u_signal[SIGTTOU] != SIG_HOLD
1137 /*
1138 					     &&
1139 	    (u.u_procp->p_flag&SDETACH)==0) {
1140 */
1141 	    ) {
1142 		gsignal(u.u_procp->p_pgrp, SIGTTOU);
1143 		sleep((caddr_t)&lbolt, TTIPRI);
1144 	}
1145 	while (u.u_count) {
1146 		cc = MIN(u.u_count, OBUFSIZ);
1147 		cp = obuf;
1148 		iomove(cp, (unsigned)cc, B_WRITE);
1149 		if (u.u_error)
1150 			break;
1151 		if (tp->t_outq.c_cc > hiwat)
1152 			goto ovhiwat;
1153 		if (tp->t_local&LFLUSHO)
1154 			continue;
1155 		if (tp->t_flags&LCASE || tp->t_local&LTILDE) {
1156 			while (cc) {
1157 				c = *cp++;
1158 				tp->t_rocount = 0;
1159 				while((c = ttyoutput(c, tp)) >= 0) {
1160 					/* out of clists, wait a bit */
1161 					ttstart(tp);
1162 					sleep((caddr_t)&lbolt, TTOPRI);
1163 					tp->t_rocount = 0;
1164 				}
1165 				--cc;
1166 				if (tp->t_outq.c_cc > hiwat)
1167 					goto ovhiwat;
1168 			}
1169 			continue;
1170 		}
1171 		while (cc) {
1172 			if (tp->t_flags&RAW || tp->t_local&LLITOUT)
1173 				ce = cc;
1174 			else {
1175 #ifdef vax
1176 				asm("	scanc	r9,(r10),_partab,$077");
1177 				asm("	subl3	r0,r9,r8");
1178 #else
1179 				ce=0;
1180 				while(((partab[*(unsigned char *)(cp+ce)]&077)==0)&&(ce<cc))
1181 					ce++;
1182 #endif
1183 				if (ce==0) {
1184 					tp->t_rocount = 0;
1185 					if (ttyoutput(*cp, tp) >= 0) {
1186 						ttstart(tp);
1187 						sleep((caddr_t)&lbolt, TTOPRI);
1188 						continue;
1189 					}
1190 					cp++;
1191 					cc--;
1192 					if (tp->t_outq.c_cc > hiwat)
1193 						goto ovhiwat;
1194 				}
1195 			}
1196 			tp->t_rocount = 0;
1197 			i=b_to_q(cp,ce,&tp->t_outq);
1198 			ce-=i;
1199 			tk_nout+=ce;
1200 			tp->t_col+=ce;
1201 			cp+=ce;
1202 			cc-=ce;
1203 			if (i) {
1204 				ttstart(tp);
1205 				sleep((caddr_t)&lbolt, TTOPRI);
1206 			}
1207 			if (ce || tp->t_outq.c_cc > hiwat)
1208 				goto ovhiwat;
1209 		}
1210 	}
1211 	ttstart(tp);
1212 	return(NULL);
1213 
1214 ovhiwat:
1215 	(void) spl5();
1216 	u.u_base -= cc;
1217 	u.u_offset -= cc;
1218 	u.u_count += cc;
1219 	if (tp->t_outq.c_cc <= hiwat) {
1220 		(void) spl0();
1221 		goto loop;
1222 	}
1223 	ttstart(tp);
1224 	if (tp->t_state & TS_NBIO) {
1225 		if (u.u_count == cnt)
1226 			u.u_error = EWOULDBLOCK;
1227 		return (NULL);
1228 	}
1229 	tp->t_state |= TS_ASLEEP;
1230 	sleep((caddr_t)&tp->t_outq, TTOPRI);
1231 	(void) spl0();
1232 	goto loop;
1233 }
1234 
1235 /*
1236  * Rubout one character from the rawq of tp
1237  * as cleanly as possible.
1238  */
1239 ttyrub(c, tp)
1240 register c;
1241 register struct tty *tp;
1242 {
1243 	register char *cp;
1244 	register int savecol;
1245 	int s;
1246 	char *nextc();
1247 
1248 	if ((tp->t_flags&ECHO)==0)
1249 		return;
1250 	tp->t_local &= ~LFLUSHO;
1251 	c &= 0377;
1252 	if (tp->t_local&LCRTBS) {
1253 		if (tp->t_rocount == 0) {
1254 			/*
1255 			 * Screwed by ttwrite; retype
1256 			 */
1257 			ttyretype(tp);
1258 			return;
1259 		}
1260 		if (c==('\t'|0200) || c==('\n'|0200))
1261 			ttyrubo(tp, 2);
1262 		else switch(partab[c&=0177] & 0177) {
1263 
1264 		case ORDINARY:
1265 			if (tp->t_flags&LCASE && c >= 'A' && c <= 'Z')
1266 				ttyrubo(tp, 2);
1267 			else
1268 				ttyrubo(tp, 1);
1269 			break;
1270 
1271 		case VTAB:
1272 		case BACKSPACE:
1273 		case CONTROL:
1274 		case RETURN:
1275 			if (tp->t_local & LCTLECH)
1276 				ttyrubo(tp, 2);
1277 			break;
1278 
1279 		case TAB:
1280 			if (tp->t_rocount < tp->t_rawq.c_cc) {
1281 				ttyretype(tp);
1282 				return;
1283 			}
1284 			s = spl5();
1285 			savecol = tp->t_col;
1286 			tp->t_lstate |= LSCNTTB;
1287 			tp->t_local |= LFLUSHO;
1288 			tp->t_col = tp->t_rocol;
1289 			for (cp = tp->t_rawq.c_cf; cp; cp = nextc(&tp->t_rawq, cp))
1290 				ttyecho(*cp, tp);
1291 			tp->t_local &= ~LFLUSHO;
1292 			tp->t_lstate &= ~LSCNTTB;
1293 			splx(s);
1294 			/*
1295 			 * savecol will now be length of the tab
1296 			 */
1297 			savecol -= tp->t_col;
1298 			tp->t_col += savecol;
1299 			if (savecol > 8)
1300 				savecol = 8;		/* overflow screw */
1301 			while (--savecol >= 0)
1302 				(void) ttyoutput('\b', tp);
1303 			break;
1304 
1305 		default:
1306 			panic("ttyrub");
1307 		}
1308 	} else if (tp->t_local&LPRTERA) {
1309 		if ((tp->t_lstate&LSERASE) == 0) {
1310 			(void) ttyoutput('\\', tp);
1311 			tp->t_lstate |= LSERASE;
1312 		}
1313 		ttyecho(c, tp);
1314 	} else
1315 		ttyecho(tp->t_erase, tp);
1316 	tp->t_rocount--;
1317 }
1318 
1319 /*
1320  * Crt back over cnt chars perhaps
1321  * erasing them.
1322  */
1323 ttyrubo(tp, cnt)
1324 register struct tty *tp;
1325 int cnt;
1326 {
1327 
1328 	while (--cnt >= 0)
1329 		ttyout(tp->t_local&LCRTERA ? "\b \b" : "\b", tp);
1330 }
1331 
1332 /*
1333  * Reprint the rawq line.
1334  * We assume c_cc has already been checked.
1335  */
1336 ttyretype(tp)
1337 register struct tty *tp;
1338 {
1339 	register char *cp;
1340 	char *nextc();
1341 	int s;
1342 
1343 	if (tlun.t_rprntc != 0377)
1344 		ttyecho(tlun.t_rprntc, tp);
1345 	(void) ttyoutput('\n', tp);
1346 	s = spl5();
1347 	for (cp = tp->t_canq.c_cf; cp; cp = nextc(&tp->t_canq, cp))
1348 		ttyecho(*cp, tp);
1349 	for (cp = tp->t_rawq.c_cf; cp; cp = nextc(&tp->t_rawq, cp))
1350 		ttyecho(*cp, tp);
1351 	tp->t_lstate &= ~LSERASE;
1352 	splx(s);
1353 	tp->t_rocount = tp->t_rawq.c_cc;
1354 	tp->t_rocol = 0;
1355 }
1356 
1357 /*
1358  * Echo a typed character to the terminal
1359  */
1360 ttyecho(c, tp)
1361 register c;
1362 register struct tty *tp;
1363 {
1364 
1365 	if ((tp->t_lstate & LSCNTTB) == 0)
1366 		tp->t_local &= ~LFLUSHO;
1367 	if ((tp->t_flags&ECHO) == 0)
1368 		return;
1369 	c &= 0377;
1370 	if (tp->t_flags&RAW) {
1371 		(void) ttyoutput(c, tp);
1372 		return;
1373 	}
1374 	if (c == '\r' && tp->t_flags&CRMOD)
1375 		c = '\n';
1376 	if (tp->t_local&LCTLECH) {
1377 		if ((c&0177) <= 037 && c!='\t' && c!='\n' || (c&0177)==0177) {
1378 			(void) ttyoutput('^', tp);
1379 			c &= 0177;
1380 			if (c == 0177)
1381 				c = '?';
1382 			else if (tp->t_flags&LCASE)
1383 				c += 'a' - 1;
1384 			else
1385 				c += 'A' - 1;
1386 		}
1387 	}
1388 	if ((tp->t_flags&LCASE) && (c >= 'A' && c <= 'Z'))
1389 		c += 'a' - 'A';
1390 	(void) ttyoutput(c & 0177, tp);
1391 }
1392 
1393 /*
1394  * Is c a break char for tp?
1395  */
1396 ttbreakc(c, tp)
1397 register c;
1398 register struct tty *tp;
1399 {
1400 	return (c == '\n' || c == tun.t_eofc || c == tun.t_brkc ||
1401 		c == '\r' && (tp->t_flags&CRMOD));
1402 }
1403 
1404 /*
1405  * send string cp to tp
1406  */
1407 ttyout(cp, tp)
1408 register char *cp;
1409 register struct tty *tp;
1410 {
1411 	register char c;
1412 
1413 	while (c = *cp++)
1414 		(void) ttyoutput(c, tp);
1415 }
1416 
1417 ttwakeup(tp)
1418 	struct tty *tp;
1419 {
1420 
1421 	if (tp->t_rsel) {
1422 		selwakeup(tp->t_rsel, tp->t_state&TS_RCOLL);
1423 		tp->t_state &= ~TS_RCOLL;
1424 		tp->t_rsel = 0;
1425 	}
1426 	wakeup((caddr_t)&tp->t_rawq);
1427 }
1428 
1429 ttsignal(tp, signo)
1430 	struct tty *tp;
1431 	int signo;
1432 {
1433 
1434 	gsignal(tp->t_pgrp, signo);
1435 }
1436