xref: /csrg-svn/sys/kern/tty.c (revision 33987)
1 /*
2  * Copyright (c) 1982, 1986 Regents of the University of California.
3  * All rights reserved.  The Berkeley software License Agreement
4  * specifies the terms and conditions for redistribution.
5  *
6  *	@(#)tty.c	7.11 (Berkeley) 04/08/88
7  */
8 
9 #include "../machine/reg.h"
10 
11 #include "param.h"
12 #include "systm.h"
13 #include "dir.h"
14 #include "user.h"
15 #include "ioctl.h"
16 #include "tty.h"
17 #define TTYDEFCHARS
18 #include "ttydefaults.h"
19 #undef TTYDEFCHARS
20 #include "termios.h"
21 #include "proc.h"
22 #include "file.h"
23 #include "conf.h"
24 #include "dkstat.h"
25 #include "uio.h"
26 #include "kernel.h"
27 #include "syslog.h"
28 
29 /*
30  * Table giving parity for characters and indicating
31  * character classes to tty driver.  In particular,
32  * if the low 6 bits are 0, then the character needs
33  * no special processing on output.
34  */
35 
36 char partab[] = {
37 	0001,0201,0201,0001,0201,0001,0001,0201,
38 	0202,0004,0003,0201,0005,0206,0201,0001,
39 	0201,0001,0001,0201,0001,0201,0201,0001,
40 	0001,0201,0201,0001,0201,0001,0001,0201,
41 	0200,0000,0000,0200,0000,0200,0200,0000,
42 	0000,0200,0200,0000,0200,0000,0000,0200,
43 	0000,0200,0200,0000,0200,0000,0000,0200,
44 	0200,0000,0000,0200,0000,0200,0200,0000,
45 	0200,0000,0000,0200,0000,0200,0200,0000,
46 	0000,0200,0200,0000,0200,0000,0000,0200,
47 	0000,0200,0200,0000,0200,0000,0000,0200,
48 	0200,0000,0000,0200,0000,0200,0200,0000,
49 	0000,0200,0200,0000,0200,0000,0000,0200,
50 	0200,0000,0000,0200,0000,0200,0200,0000,
51 	0200,0000,0000,0200,0000,0200,0200,0000,
52 	0000,0200,0200,0000,0200,0000,0000,0201,
53 
54 	/*
55 	 * 7 bit ascii ends with the last character above,
56 	 * but we contine through all 256 codes for the sake
57 	 * of the tty output routines which use special vax
58 	 * instructions which need a 256 character trt table.
59 	 */
60 
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 	0007,0007,0007,0007,0007,0007,0007,0007,
68 	0007,0007,0007,0007,0007,0007,0007,0007,
69 	0007,0007,0007,0007,0007,0007,0007,0007,
70 	0007,0007,0007,0007,0007,0007,0007,0007,
71 	0007,0007,0007,0007,0007,0007,0007,0007,
72 	0007,0007,0007,0007,0007,0007,0007,0007,
73 	0007,0007,0007,0007,0007,0007,0007,0007,
74 	0007,0007,0007,0007,0007,0007,0007,0007,
75 	0007,0007,0007,0007,0007,0007,0007,0007,
76 	0007,0007,0007,0007,0007,0007,0007,0007
77 };
78 
79 /*
80  * Input mapping table-- if an entry is non-zero, when the
81  * corresponding character is typed preceded by "\" the escape
82  * sequence is replaced by the table value.  Mostly used for
83  * upper-case only terminals.
84  */
85 char	maptab[] ={
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,000,
89 	000,000,000,000,000,000,000,000,
90 	000,'|',000,000,000,000,000,'`',
91 	'{','}',000,000,000,000,000,000,
92 	000,000,000,000,000,000,000,000,
93 	000,000,000,000,000,000,000,000,
94 	000,000,000,000,000,000,000,000,
95 	000,000,000,000,000,000,000,000,
96 	000,000,000,000,000,000,000,000,
97 	000,000,000,000,000,000,'~',000,
98 	000,'A','B','C','D','E','F','G',
99 	'H','I','J','K','L','M','N','O',
100 	'P','Q','R','S','T','U','V','W',
101 	'X','Y','Z',000,000,000,000,000,
102 };
103 
104 short	tthiwat[16] =
105    { 100,100,100,100,100,100,100,200,200,400,400,400,650,650,1300,2000 };
106 short	ttlowat[16] =
107    {  30, 30, 30, 30, 30, 30, 30, 50, 50,120,120,120,125,125,125,125 };
108 
109 extern struct tty *constty;		/* temporary virtual console */
110 extern char partab[], maptab[];
111 
112 /*
113  * Debugging aids
114  */
115 #define dprintf 	if (tp->t_trace & TTRACE_IO)printf
116 
117 /*
118  * Is 'c' a line delimiter ("break" character)?
119  */
120 #define ttbreakc(c) (c == '\n' || CCEQ(cc[VEOF], c) || \
121 		CCEQ(cc[VEOL], c) || CCEQ(cc[VEOL2], c))
122 
123 ttychars(tp)
124 	struct tty *tp;
125 {
126 	bcopy(ttydefchars, tp->t_cc, sizeof(ttydefchars));
127 }
128 
129 /*
130  *
131  * Wait for output to drain, then flush input waiting.
132  */
133 ttywflush(tp)
134 	register struct tty *tp;
135 {
136 
137 	ttywait(tp);
138 	ttyflush(tp, FREAD);
139 }
140 
141 /*
142  * Wait for output to drain.
143  */
144 ttywait(tp)
145 	register struct tty *tp;
146 {
147 	register int s = spltty();
148 
149 	while ((tp->t_outq.c_cc || tp->t_state&TS_BUSY) &&
150 	    tp->t_state&TS_CARR_ON && tp->t_oproc) {
151 		(*tp->t_oproc)(tp);
152 		tp->t_state |= TS_ASLEEP;
153 		sleep((caddr_t)&tp->t_outq, TTOPRI);
154 	}
155 	splx(s);
156 }
157 
158 /*
159  * Flush all TTY queues
160  */
161 ttyflush(tp, rw)
162 	register struct tty *tp;
163 {
164 	register s;
165 
166 	s = spltty();
167 	if (rw & FREAD) {
168 		while (getc(&tp->t_canq) >= 0)
169 			;
170 		wakeup((caddr_t)&tp->t_rawq);
171 	}
172 	if (rw & FWRITE) {
173 		wakeup((caddr_t)&tp->t_outq);
174 		tp->t_state &= ~TS_TTSTOP;
175 		(*cdevsw[major(tp->t_dev)].d_stop)(tp, rw);
176 		while (getc(&tp->t_outq) >= 0)
177 			;
178 	}
179 	if (rw & FREAD) {
180 		while (getc(&tp->t_rawq) >= 0)
181 			;
182 		tp->t_rocount = 0;
183 		tp->t_rocol = 0;
184 		tp->t_state &= ~TS_LOCAL;
185 	}
186 	splx(s);
187 }
188 
189 /*
190  * Send stop character on input overflow.
191  */
192 ttyblock(tp)
193 	register struct tty *tp;
194 {
195 	register x;
196 
197 	x = tp->t_rawq.c_cc + tp->t_canq.c_cc;
198 	if (tp->t_rawq.c_cc > TTYHOG) {
199 		ttyflush(tp, FREAD|FWRITE);
200 		tp->t_state &= ~TS_TBLOCK;
201 	}
202 	/*
203 	 * Block further input iff:
204 	 * Current input > threshold AND input is available to user program
205 	 */
206 	if (x >= TTYHOG/2 &&
207 	    (!(tp->t_lflag&ICANON)) || (tp->t_canq.c_cc > 0) &&
208 	    tp->t_cc[VSTOP] != POSIX_V_DISABLE) {
209 		if (putc(tp->t_cc[VSTOP], &tp->t_outq)==0) {
210 			tp->t_state |= TS_TBLOCK;
211 			ttstart(tp);
212 		}
213 	}
214 }
215 
216 /*
217  * Restart typewriter output following a delay
218  * timeout.
219  * The name of the routine is passed to the timeout
220  * subroutine and it is called during a clock interrupt.
221  */
222 ttrstrt(tp)
223 	register struct tty *tp;
224 {
225 
226 	if (tp == 0)
227 		panic("ttrstrt");
228 	tp->t_state &= ~TS_TIMEOUT;
229 	ttstart(tp);
230 }
231 
232 /*
233  * Start output on the typewriter. It is used from the top half
234  * after some characters have been put on the output queue,
235  * from the interrupt routine to transmit the next
236  * character, and after a timeout has finished.
237  */
238 ttstart(tp)
239 	register struct tty *tp;
240 {
241 
242 	if (tp->t_oproc)		/* kludge for pty */
243 		(*tp->t_oproc)(tp);
244 }
245 
246 /*
247  * Common code for tty ioctls.
248  */
249 /*ARGSUSED*/
250 ttioctl(tp, com, data, flag)
251 	register struct tty *tp;
252 	caddr_t data;
253 {
254 	extern int nldisp;
255 	int soft;
256 	int s;
257 
258 
259 	/*
260 	 * If the ioctl involves modification,
261 	 * hang if in the background.
262 	 */
263 	switch (com) {
264 
265 	case TIOCSETD:
266 	case TIOCFLUSH:
267 	case TIOCSPGRP:
268 	case TIOCSTI:
269 	case TIOCSWINSZ:
270 	case TIOCSETA:
271 	case TIOCSETAW:
272 	case TIOCSETAF:
273 	case TIOCSETAS:
274 	case TIOCSETAWS:
275 	case TIOCSETAFS:
276 		while (tp->t_line == POSXDISC &&
277 		   u.u_procp->p_pgrp != tp->t_pgrp && tp == u.u_ttyp &&
278 		   (u.u_procp->p_flag&SVFORK) == 0 &&
279 		   !(u.u_procp->p_sigignore & sigmask(SIGTTOU)) &&
280 		   !(u.u_procp->p_sigmask & sigmask(SIGTTOU))) {
281 			gsignal(u.u_procp->p_pgrp, SIGTTOU);
282 			sleep((caddr_t)&lbolt, TTOPRI);
283 		}
284 		break;
285 	}
286 
287 	/*
288 	 * Process the ioctl.
289 	 */
290 	switch (com) {
291 
292 	/* get discipline number */
293 	case TIOCGETD:
294 		*(int *)data = tp->t_line;
295 		break;
296 
297 	/* set line discipline */
298 	case TIOCSETD: {
299 		register int t = *(int *)data;
300 		dev_t dev = tp->t_dev;
301 		int error = 0;
302 
303 		if ((unsigned) t >= nldisp)
304 			return (ENXIO);
305 		if (t != tp->t_line) {
306 			s = spltty();
307 			(*linesw[tp->t_line].l_close)(tp);
308 			error = (*linesw[t].l_open)(dev, tp);
309 			if (error) {
310 				(void)(*linesw[tp->t_line].l_open)(dev, tp);
311 				splx(s);
312 				return (error);
313 			}
314 			tp->t_line = t;
315 			splx(s);
316 		}
317 		if (tp->t_trace & TTRACE_STATE)
318 			ttytrace(com, tp);
319 		break;
320 	}
321 
322 	/* prevent more opens on channel */
323 	case TIOCEXCL:
324 		tp->t_state |= TS_XCLUDE;
325 		break;
326 
327 	case TIOCNXCL:
328 		tp->t_state &= ~TS_XCLUDE;
329 		break;
330 
331 	case TIOCHPCL:
332 		tp->t_cflag |= HUPCL;
333 		break;
334 
335 	case TIOCFLUSH: {
336 		register int flags = *(int *)data;
337 
338 		if (flags == 0)
339 			flags = FREAD|FWRITE;
340 		else
341 			flags &= FREAD|FWRITE;
342 		ttyflush(tp, flags);
343 		break;
344 	}
345 
346 	/* return number of characters immediately available */
347 	case FIONREAD:
348 		*(off_t *)data = ttnread(tp);
349 		break;
350 
351 	case TIOCOUTQ:
352 		*(int *)data = tp->t_outq.c_cc;
353 		break;
354 
355 	case TIOCSTOP:
356 		s = spltty();
357 		if ((tp->t_state&TS_TTSTOP) == 0) {
358 			tp->t_state |= TS_TTSTOP;
359 			(*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
360 		}
361 		splx(s);
362 		break;
363 
364 	case TIOCSTART:
365 		s = spltty();
366 		if ((tp->t_state&TS_TTSTOP) || (tp->t_lflag&FLUSHO)) {
367 			tp->t_state &= ~TS_TTSTOP;
368 			tp->t_lflag &= ~FLUSHO;
369 			ttstart(tp);
370 		}
371 		splx(s);
372 		break;
373 
374 	/*
375 	 * Simulate typing of a character at the terminal.
376 	 */
377 	case TIOCSTI:
378 		if (u.u_uid && (flag & FREAD) == 0)
379 			return (EPERM);
380 		if (u.u_uid && u.u_ttyp != tp)
381 			return (EACCES);
382 		(*linesw[tp->t_line].l_rint)(*(char *)data, tp);
383 		break;
384 
385 	case TIOCGETA: {
386 		struct termios *t = (struct termios *)data;
387 		bcopy(&tp->t_termio, t, sizeof(struct termios));
388 		if (tp->t_trace & TTRACE_STATE)
389 			ttytrace(com, tp);
390 		break;
391 	}
392 
393 	case TIOCSETAS:
394 	case TIOCSETAWS:
395 	case TIOCSETAFS:
396 		soft = 1;
397 		goto set;
398 	case TIOCSETA:
399 	case TIOCSETAW:
400 	case TIOCSETAF:
401 		soft = 0;
402 set:
403 		{
404 		register struct termios *t = (struct termios *)data;
405 
406 		s = spltty();
407 		if (com == TIOCSETAF || com == TIOCSETAFS)
408 			ttywflush(tp);
409 		else {
410 			if (com == TIOCSETAW || com == TIOCSETAWS)
411 				ttywait(tp);
412 			if ((t->c_lflag&ICANON) != (tp->t_lflag&ICANON))
413 				if (t->c_lflag&ICANON) {
414 					tp->t_lflag |= PENDIN;
415 					ttwakeup(tp);
416 				}
417 				else {
418 					struct clist tq;
419 
420 					catq(&tp->t_rawq, &tp->t_canq);
421 					tq = tp->t_rawq;
422 					tp->t_rawq = tp->t_canq;
423 					tp->t_canq = tq;
424 				}
425 		}
426 		tp->t_iflag = t->c_iflag;
427 		tp->t_oflag = t->c_oflag;
428 		tp->t_lflag = t->c_lflag;
429 		bcopy(t->c_cc, tp->t_cc, sizeof(t->c_cc));
430 		if (!soft) {
431 			tp->t_cflag = t->c_cflag;
432 			tp->t_ispeed = t->c_ispeed;
433 			tp->t_ospeed = t->c_ospeed;
434 		}
435 		splx(s);
436 		if (tp->t_trace & TTRACE_STATE)
437 			ttytrace(com, tp);
438 		break;
439 	}
440 
441 	case TIOCTRACE:
442 		tp->t_trace = *(int *)data;
443 		break;
444 
445 	case FIONBIO:
446 		if (*(int *)data)
447 			tp->t_state |= TS_NBIO;
448 		else
449 			tp->t_state &= ~TS_NBIO;
450 		break;
451 
452 	case FIOASYNC:
453 		if (*(int *)data)
454 			tp->t_state |= TS_ASYNC;
455 		else
456 			tp->t_state &= ~TS_ASYNC;
457 		break;
458 
459 
460 	/*
461 	 * Allow SPGRP only if tty is open for reading.
462 	 * Quick check: if we can find a process in the new pgrp,
463 	 * this user must own that process.
464 	 * SHOULD VERIFY THAT PGRP IS IN USE AND IS THIS USER'S.
465 	 */
466 	case TIOCSPGRP: {
467 		struct proc *p;
468 		int pgrp = *(int *)data;
469 
470 		if (u.u_uid && (flag & FREAD) == 0)
471 			return (EPERM);
472 		p = pfind(pgrp);
473 		if (p && p->p_pgrp == pgrp &&
474 		    p->p_uid != u.u_uid && u.u_uid && !inferior(p))
475 			return (EPERM);
476 		tp->t_pgrp = pgrp;
477 		break;
478 	}
479 
480 	case TIOCGPGRP:
481 		*(int *)data = tp->t_pgrp;
482 		break;
483 
484 	case TIOCSWINSZ:
485 		if (bcmp((caddr_t)&tp->t_winsize, data,
486 		    sizeof (struct winsize))) {
487 			tp->t_winsize = *(struct winsize *)data;
488 			gsignal(tp->t_pgrp, SIGWINCH);
489 		}
490 		break;
491 
492 	case TIOCGWINSZ:
493 		*(struct winsize *)data = tp->t_winsize;
494 		break;
495 
496 	case TIOCCONS:
497 		if (*(int *)data) {
498 			if (constty != NULL)
499 				return (EBUSY);
500 #ifndef	UCONSOLE
501 			if (!suser())
502 				return (EPERM);
503 #endif
504 			constty = tp;
505 		} else if (tp == constty)
506 			constty = NULL;
507 		break;
508 
509 	/* allow old ioctls for now */
510 	case TIOCGETP:
511 	case TIOCSETP:
512 	case TIOCSETN:
513 	case TIOCGETC:
514 	case TIOCSETC:
515 	case TIOCSLTC:
516 	case TIOCGLTC:
517 	case TIOCLBIS:
518 	case TIOCLBIC:
519 	case TIOCLSET:
520 	case TIOCLGET:
521 		return(ottioctl(tp, com, data, flag));
522 
523 	default:
524 		return (-1);
525 	}
526 	return (0);
527 }
528 
529 /*
530  * DEBUG - to be removed
531  */
532 ttytrace(ioc, tp)
533 	struct tty *tp;
534 {
535 	register u_char *cc = tp->t_cc;
536 	char comm[MAXCOMLEN+1];
537 	static int seq = 0;
538 
539 	bcopy(u.u_comm, comm, MAXCOMLEN+1);
540 	comm[MAXCOMLEN] = '\0';
541 
542 	/* trace changes to line disciplines */
543 	if (ioc == TIOCSETD) {
544 		log(LOG_LOCAL4|LOG_DEBUG, "%s:%x:%x:%x:%x\n",
545 		    comm, ioc, u.u_procp->p_pid, tp->t_dev, tp->t_line);
546 		return;
547 	}
548 
549 	/*
550 	 * format for the trace record is:
551 	 *
552 	 * u_comm:ioctl:pid:dev_t:ldisc:iflag:oflag:lflag:cflag:ispeed:
553 	 *    ospeed:cc's...:seq
554 	 *
555 	 * u_comm is a string and all other values are hex. "cc's..."
556 	 * stands for control chars 0 through NCC-1.  seq is a sequence #
557 	 * to force syslogd to log every entry (rather than hold them to
558 	 * print "last message repeated...".
559 	 */
560 	log(LOG_LOCAL4|LOG_DEBUG, "%s:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x:%x\n",
561 		comm, ioc, u.u_procp->p_pid, tp->t_dev, tp->t_line,
562 		tp->t_iflag, tp->t_oflag, tp->t_lflag, tp->t_cflag,
563 		tp->t_ispeed, tp->t_ospeed, cc[0], cc[1], cc[2], cc[3],
564 		cc[4], cc[5], cc[6], cc[7], cc[8], cc[9], cc[10], cc[11],
565 		cc[12], cc[13], cc[14], cc[15], cc[16], cc[17], cc[18],
566 		cc[19], seq++);
567 }
568 
569 ttnread(tp)
570 	struct tty *tp;
571 {
572 	int nread = 0;
573 
574 	if (tp->t_lflag & PENDIN)
575 		ttypend(tp);
576 	nread = tp->t_canq.c_cc;
577 	if (tp->t_lflag & ICANON == 0)
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 = spltty();
589 
590 	switch (rw) {
591 
592 	case FREAD:
593 		nread = ttnread(tp);
594 		if (nread > 0 || (tp->t_state & TS_CARR_ON) == 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 /*
619  * Initial open of tty, or (re)entry to line discipline.
620  * Establish a process group for distribution of
621  * quits and interrupts from the tty.
622  */
623 ttyopen(dev, tp)
624 	dev_t dev;
625 	register struct tty *tp;
626 {
627 	register struct proc *pp;
628 
629 	pp = u.u_procp;
630 	tp->t_dev = dev;
631 	if (pp->p_pgrp == 0) {	/* XXX - this has got to change */
632 		u.u_ttyp = tp;
633 		u.u_ttyd = dev;
634 		if (tp->t_pgrp == 0)
635 			tp->t_pgrp = pp->p_pid;
636 		pp->p_pgrp = tp->t_pgrp;
637 	}
638 	tp->t_state &= ~TS_WOPEN;
639 	if ((tp->t_state & TS_ISOPEN) == 0) {
640 		tp->t_state |= TS_ISOPEN;
641 		bzero((caddr_t)&tp->t_winsize, sizeof(tp->t_winsize));
642 		/*
643 		 * CHANGE: used to do a ttywflush() if it was the
644 		 *  old (old) line discipline.
645 		 */
646 	}
647 	return (0);
648 }
649 
650 /*
651  * "close" a line discipline
652  */
653 ttylclose(tp)
654 	register struct tty *tp;
655 {
656 
657 	ttywflush(tp);
658 }
659 
660 /*
661  * clean tp on last close
662  */
663 ttyclose(tp)
664 	register struct tty *tp;
665 {
666 
667 	if (constty == tp)
668 		constty = NULL;
669 	ttyflush(tp, FREAD|FWRITE);
670 	tp->t_pgrp = 0;
671 	tp->t_state = 0;
672 }
673 
674 /*
675  * Handle modem control transition on a tty.
676  * Flag indicates new state of carrier.
677  * Returns 0 if the line should be turned off, otherwise 1.
678  */
679 ttymodem(tp, flag)
680 	register struct tty *tp;
681 {
682 
683 	if ((tp->t_state&TS_WOPEN) == 0 && (tp->t_lflag & MDMBUF)) {
684 		/*
685 		 * MDMBUF: do flow control according to carrier flag
686 		 */
687 		if (flag) {
688 			tp->t_state &= ~TS_TTSTOP;
689 			ttstart(tp);
690 		} else if ((tp->t_state&TS_TTSTOP) == 0) {
691 			tp->t_state |= TS_TTSTOP;
692 			(*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
693 		}
694 	} else if (flag == 0) {
695 		/*
696 		 * Lost carrier.
697 		 */
698 		tp->t_state &= ~TS_CARR_ON;
699 		if (tp->t_state & TS_ISOPEN) {
700 			if ((tp->t_lflag & NOHANG) == 0) {
701 				gsignal(tp->t_pgrp, SIGHUP);
702 				gsignal(tp->t_pgrp, SIGCONT);
703 				ttyflush(tp, FREAD|FWRITE);
704 				return (0);
705 			}
706 		}
707 	} else {
708 		/*
709 		 * Carrier now on.
710 		 */
711 		tp->t_state |= TS_CARR_ON;
712 		wakeup((caddr_t)&tp->t_rawq);
713 	}
714 	return (1);
715 }
716 
717 /*
718  * Default modem control routine (for other line disciplines).
719  * Return argument flag, to turn off device on carrier drop.
720  */
721 nullmodem(tp, flag)
722 	register struct tty *tp;
723 	int flag;
724 {
725 
726 	if (flag)
727 		tp->t_state |= TS_CARR_ON;
728 	else
729 		tp->t_state &= ~TS_CARR_ON;
730 	return (flag);
731 }
732 
733 /*
734  * reinput pending characters after state switch
735  * call at spltty().
736  */
737 ttypend(tp)
738 	register struct tty *tp;
739 {
740 	struct clist tq;
741 	register c;
742 
743 	tp->t_lflag &= ~PENDIN;
744 	tp->t_state |= TS_TYPEN;
745 	tq = tp->t_rawq;
746 	tp->t_rawq.c_cc = 0;
747 	tp->t_rawq.c_cf = tp->t_rawq.c_cl = 0;
748 	while ((c = getc(&tq)) >= 0)
749 		ttyinput(c, tp);
750 	tp->t_state &= ~TS_TYPEN;
751 }
752 
753 /*
754  *
755  * Place a character on raw TTY input queue,
756  * putting in delimiters and waking up top
757  * half as needed.  Also echo if required.
758  * The arguments are the character and the
759  * appropriate tty structure.
760  */
761 ttyinput(c, tp)
762 	register c;
763 	register struct tty *tp;
764 {
765 	register int iflag = tp->t_iflag;
766 	register int lflag = tp->t_lflag;
767 	register u_char *cc = tp->t_cc;
768 	int i, err;
769 
770 	/*
771 	 * If input is pending take it first.
772 	 */
773 	if (lflag&PENDIN)
774 		ttypend(tp);
775 
776 	tk_nin++;
777 
778 	/*
779 	 * Handle exceptional conditions (break, parity, framing).
780 	 */
781 	if (err = (c&TTY_ERRORMASK)) {
782 		c &= TTY_CHARMASK;
783 		if (err&TTY_FE && !c) {		/* break */
784 			if (iflag&IGNBRK)
785 				goto endcase;
786 			else if (iflag&BRKINT && lflag&ISIG &&
787 				(cc[VINTR] != POSIX_V_DISABLE))
788 				c = cc[VINTR];
789 			else
790 				c = 0;
791 		} else if ((err&TTY_PE && iflag&INPCK) || err&TTY_FE) {
792 			if (iflag&IGNPAR)
793 				goto endcase;
794 			else if (iflag&PARMRK) {
795 				ttyinput(0377, tp);
796 				ttyinput(0, tp);
797 			} else
798 				c = 0;
799 		}
800 	}
801 
802 	dprintf("<%o>\n", c);
803 
804 	/*
805 	 * In tandem mode, check high water mark.
806 	 */
807 	if (iflag&IXOFF)
808 		ttyblock(tp);
809 
810 	/*
811 	 * Ignore any high bit added during
812 	 * previous ttyinput processing.
813 	 */
814 	if ((tp->t_state&TS_TYPEN) == 0 && (iflag&ISTRIP))
815 		c &= 0177;
816 	/*
817 	 * Check for literal nexting very first
818 	 */
819 	if (tp->t_state&TS_LNCH) {
820 		c |= 0200;
821 		tp->t_state &= ~TS_LNCH;
822 	}
823 
824 	/*
825 	 * Scan for special characters.  This code
826 	 * is really just a big case statement with
827 	 * non-constant cases.  The bottom of the
828 	 * case statement is labeled ``endcase'', so goto
829 	 * it after a case match, or similar.
830 	 */
831 
832 	/*
833 	 * Extensions to POSIX input modes which aren't controlled
834 	 * by ICANON, ISIG, or IXON.
835 	 */
836 	if (iflag&IEXTEN) {
837 		if (CCEQ(cc[VLNEXT],c) && (iflag&ISTRIP)) {
838 			if (lflag&ECHO)
839 				ttyout("^\b", tp); /*XXX - presumes too much */
840 			tp->t_state |= TS_LNCH;
841 			goto endcase;
842 		}
843 		if (CCEQ(cc[VFLUSHO],c)) {
844 			if (lflag&FLUSHO)
845 				tp->t_lflag &= ~FLUSHO;
846 			else {
847 				ttyflush(tp, FWRITE);
848 				ttyecho(c, tp);
849 				if (tp->t_rawq.c_cc + tp->t_canq.c_cc)
850 					ttyretype(tp);
851 				tp->t_lflag |= FLUSHO;
852 			}
853 			goto startoutput;
854 		}
855 	}
856 
857 	/*
858 	 * Signals.
859 	 */
860 	if (lflag&ISIG) {
861 		if (CCEQ(cc[VINTR], c) || CCEQ(cc[VQUIT], c)) {
862 			if ((lflag&NOFLSH) == 0)
863 				ttyflush(tp, FREAD|FWRITE);
864 			ttyecho(c, tp);
865 			gsignal(tp->t_pgrp, CCEQ(cc[VINTR],c) ?
866 				SIGINT : SIGQUIT);
867 			goto endcase;
868 		}
869 		if (CCEQ(cc[VSUSP],c)) {
870 			if ((lflag&NOFLSH) == 0)
871 				ttyflush(tp, FREAD);
872 			ttyecho(c, tp);
873 			gsignal(tp->t_pgrp, SIGTSTP);
874 			goto endcase;
875 		}
876 	}
877 
878 	/*
879 	 * Handle start/stop characters.
880 	 */
881 	if (iflag&IXON) {
882 		if (CCEQ(cc[VSTOP],c)) {
883 			if ((tp->t_state&TS_TTSTOP) == 0) {
884 				tp->t_state |= TS_TTSTOP;
885 				(*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
886 				return;
887 			}
888 			if (!CCEQ(cc[VSTART], c))
889 				return;
890 			/*
891 			 * if VSTART == VSTOP we toggle
892 			 */
893 			goto endcase;
894 		}
895 		if (CCEQ(cc[VSTART], c))
896 			goto restartoutput;
897 	}
898 
899 	/*
900 	 * IGNCR, ICRNL, & INLCR
901 	 */
902 	if (c == '\r') {
903 		if (iflag&IGNCR)
904 			goto endcase;
905 		else if (iflag&ICRNL)
906 			c = '\n';
907 	}
908 	else if (c == '\n' && iflag&INLCR)
909 		c = '\r';
910 
911 #ifdef notdef
912 	/*
913 	 * We'd like to completely remove it.
914 	 */
915 	if (tp->t_flags & LCASE && c <= 0177) {
916 		if (tp->t_state&TS_BKSL) {
917 			ttyrub(unputc(&tp->t_rawq), tp);
918 			if (maptab[c])
919 				c = maptab[c];
920 			c |= 0200;
921 			tp->t_state &= ~(TS_BKSL|TS_QUOT);
922 		} else if (c >= 'A' && c <= 'Z')
923 			c += 'a' - 'A';
924 		else if (c == '\\')
925 			tp->t_state |= TS_BKSL;
926 	}
927 #endif /*notdef*/
928 
929 	/*
930 	 * Non canonical mode, don't process line editing
931 	 * characters; check high water mark for wakeup.
932 	 *
933 	 */
934 	if (!(lflag&ICANON)) {
935 		if (tp->t_rawq.c_cc > TTYHOG) {
936 			if (iflag&IMAXBEL) {
937 				if (tp->t_outq.c_cc < TTHIWAT(tp))
938 					(void) ttyoutput(CTRL('g'), tp);
939 			} else
940 				ttyflush(tp, FREAD | FWRITE);
941 		} else if (putc(c, &tp->t_rawq) >= 0) {
942 			ttwakeup(tp);
943 			ttyecho(c, tp);
944 		}
945 		goto endcase;
946 	}
947 
948 	/*
949 	 * From here on down canonical mode character
950 	 * processing takes place.
951 	 */
952 
953 	/*
954 	 * Oldstyle quoting of erase, kill, and eof chars.
955 	 *
956 	 * Historically is '\' , but can be changed (read: disabled)
957 	 * with the VQUOTE subscript.
958 	 */
959 	if ((tp->t_state&TS_QUOT) &&
960 	    (CCEQ(cc[VERASE], c) || CCEQ(cc[VKILL], c) || CCEQ(cc[VEOF], c))) {
961 		ttyrub(unputc(&tp->t_rawq), tp);
962 		c |= 0200;
963 	}
964 
965 	/*
966 	 * erase (^H / ^?)
967 	 */
968 	if (CCEQ(cc[VERASE], c)) {
969 		if (tp->t_rawq.c_cc)
970 			ttyrub(unputc(&tp->t_rawq), tp);
971 		goto endcase;
972 	}
973 	/*
974 	 * kill (^X / ^U)
975 	 */
976 	if (CCEQ(cc[VKILL], c)) {
977 		if (lflag&ECHOKE &&
978 		    tp->t_rawq.c_cc == tp->t_rocount) {
979 			while (tp->t_rawq.c_cc)
980 				ttyrub(unputc(&tp->t_rawq), tp);
981 		} else {
982 			ttyecho(c, tp);
983 			if (lflag&ECHOK || lflag&ECHOKE)
984 				ttyecho('\n', tp);
985 			while (getc(&tp->t_rawq) > 0)
986 				;
987 			tp->t_rocount = 0;
988 		}
989 		tp->t_state &= ~TS_LOCAL;
990 		goto endcase;
991 	}
992 
993 	/*
994 	 * word erase (^W)
995 	 */
996 	if (CCEQ(cc[VWERASE], c)) {
997 		if (tp->t_rawq.c_cc == 0)
998 			goto endcase;
999 		do {
1000 			c = unputc(&tp->t_rawq);
1001 			if (c != ' ' && c != '\t')
1002 				goto erasenb;
1003 			ttyrub(c, tp);
1004 		} while (tp->t_rawq.c_cc);
1005 		goto endcase;
1006 erasenb:
1007 		do {
1008 			ttyrub(c, tp);
1009 			if (tp->t_rawq.c_cc == 0)
1010 				goto endcase;
1011 			c = unputc(&tp->t_rawq);
1012 		} while (c != ' ' && c != '\t');
1013 		(void) putc(c, &tp->t_rawq);
1014 		goto endcase;
1015 	}
1016 	/*
1017 	 * reprint line (^R)
1018 	 */
1019 	if (CCEQ(cc[VREPRINT], c)) {
1020 		ttyretype(tp);
1021 		goto endcase;
1022 	}
1023 
1024 	/*
1025 	 * Check for input buffer overflow
1026 	 */
1027 	if (tp->t_rawq.c_cc+tp->t_canq.c_cc >= TTYHOG) {
1028 		if (iflag&IMAXBEL) {
1029 			if (tp->t_outq.c_cc < TTHIWAT(tp))
1030 				(void) ttyoutput(CTRL('g'), tp);
1031 		} else
1032 			ttyflush(tp, FREAD | FWRITE);
1033 		goto endcase;
1034 	}
1035 
1036 	/*
1037 	 * Put data char in q for user and
1038 	 * wakeup on seeing a line delimiter.
1039 	 */
1040 	if (putc(c, &tp->t_rawq) >= 0) {
1041 		if (ttbreakc(c)) {
1042 			tp->t_rocount = 0;
1043 			catq(&tp->t_rawq, &tp->t_canq);
1044 			ttwakeup(tp);
1045 		} else if (tp->t_rocount++ == 0)
1046 			tp->t_rocol = tp->t_col;
1047 		tp->t_state &= ~TS_QUOT;
1048 		if (CCEQ(cc[VQUOTE], c) && (iflag&ISTRIP))
1049 			tp->t_state |= TS_QUOT;	/* '\' escape */
1050 		if (tp->t_state&TS_ERASE) {
1051 			/*
1052 			 * end of prterase \.../
1053 			 */
1054 			tp->t_state &= ~TS_ERASE;
1055 			(void) ttyoutput('/', tp);
1056 		}
1057 		i = tp->t_col;
1058 		ttyecho(c, tp);
1059 		if (CCEQ(cc[VEOF], c) && lflag&ECHO) {
1060 			/*
1061 			 * Place the cursor over the '^' of the ^D.
1062 			 */
1063 			i = MIN(2, tp->t_col - i);
1064 			while (i > 0) {
1065 				(void) ttyoutput('\b', tp);
1066 				i--;
1067 			}
1068 		}
1069 	}
1070 endcase:
1071 	/*
1072 	 * IXANY means allow any character to restart output.
1073 	 */
1074 	if (tp->t_state&TS_TTSTOP && (iflag&IXANY == 0)
1075 	    && cc[VSTART] != cc[VSTOP])
1076 		return;
1077 
1078 restartoutput:
1079 	tp->t_state &= ~TS_TTSTOP;
1080 	tp->t_lflag &= ~FLUSHO;
1081 startoutput:
1082 	ttstart(tp);
1083 }
1084 
1085 /*
1086  * Put character on TTY output queue, adding delays,
1087  * expanding tabs, and handling the CR/NL bit.
1088  * This is called both from the top half for output,
1089  * and from interrupt level for echoing.
1090  * The arguments are the character and the tty structure.
1091  * Returns < 0 if putc succeeds, otherwise returns char to resend
1092  * Must be recursive.
1093  */
1094 ttyoutput(c, tp)
1095 	register c;
1096 	register struct tty *tp;
1097 {
1098 	register char *colp;
1099 	register ctype;
1100 
1101 	if (!(tp->t_oflag&OPOST)) {
1102 		if (tp->t_lflag&FLUSHO)
1103 			return (-1);
1104 		if (putc(c, &tp->t_outq))
1105 			return (c);
1106 		tk_nout++;
1107 		return (-1);
1108 	}
1109 	c &= 0377;
1110 	/*
1111 	 * Turn tabs to spaces as required
1112 	 */
1113 	if (c == '\t' && tp->t_oflag&OXTABS ) {
1114 		register int s;
1115 
1116 		c = 8 - (tp->t_col&7);
1117 		if ((tp->t_lflag&FLUSHO) == 0) {
1118 			s = spltty();		/* don't interrupt tabs */
1119 			c -= b_to_q("        ", c, &tp->t_outq);
1120 			tk_nout += c;
1121 			splx(s);
1122 		}
1123 		tp->t_col += c;
1124 		return (c ? -1 : '\t');
1125 	}
1126 	tk_nout++;
1127 #ifdef notdef
1128 	/*
1129 	 * for upper-case-only terminals,
1130 	 * generate escapes.
1131 	 */
1132 	if (tp->t_flags&LCASE) {
1133 		colp = "({)}!|^~'`";
1134 		while (*colp++)
1135 			if (c == *colp++) {
1136 				if (ttyoutput('\\', tp) >= 0)
1137 					return (c);
1138 				c = colp[-2];
1139 				break;
1140 			}
1141 		if ('A' <= c && c <= 'Z') {
1142 			if (ttyoutput('\\', tp) >= 0)
1143 				return (c);
1144 		} else if ('a' <= c && c <= 'z')
1145 			c += 'A' - 'a';
1146 	}
1147 #endif
1148 
1149 	/*
1150 	 * turn <nl> to <cr><lf> if desired.
1151 	 */
1152 	if (c == '\n' && (tp->t_oflag&ONLCR) && ttyoutput('\r', tp) >= 0)
1153 			return (c);
1154 #ifdef notdef
1155 	if (c == '~' && tp->t_flags&TILDE)
1156 		c = '`';
1157 #endif
1158 	if ((tp->t_lflag&FLUSHO) == 0 && putc(c, &tp->t_outq))
1159 		return (c);
1160 	/*
1161 	 * Calculate delays.
1162 	 * The numbers here represent clock ticks
1163 	 * and are not necessarily optimal for all terminals.
1164 	 * The delays are indicated by characters above 0200.
1165 	 * In raw mode there are no delays and the
1166 	 * transmission path is 8 bits wide.
1167 	 *
1168 	 * SHOULD JUST ALLOW USER TO SPECIFY DELAYS
1169 	 */
1170 	colp = &tp->t_col;
1171 	ctype = partab[c];
1172 	c = 0;
1173 	switch (ctype&077) {
1174 
1175 	case ORDINARY:
1176 		(*colp)++;
1177 
1178 	case CONTROL:
1179 		break;
1180 
1181 	case BACKSPACE:
1182 		if (*colp)
1183 			(*colp)--;
1184 		break;
1185 
1186 	/*
1187 	 * This macro is close enough to the correct thing;
1188 	 * it should be replaced by real user settable delays
1189 	 * in any event...
1190 	 */
1191 #define	mstohz(ms)	(((ms) * hz) >> 10)
1192 	case NEWLINE:
1193 		ctype = (tp->t_flags >> 8) & 03;
1194 		if (ctype == 1) { /* tty 37 */
1195 			if (*colp > 0) {
1196 				c = (((unsigned)*colp) >> 4) + 3;
1197 				if ((unsigned)c > 6)
1198 					c = 6;
1199 			}
1200 		} else if (ctype == 2) /* vt05 */
1201 			c = mstohz(100);
1202 		*colp = 0;
1203 		break;
1204 
1205 	case TAB:
1206 		ctype = (tp->t_flags >> 10) & 03;
1207 		if (ctype == 1) { /* tty 37 */
1208 			c = 1 - (*colp | ~07);
1209 			if (c < 5)
1210 				c = 0;
1211 		}
1212 		*colp |= 07;
1213 		(*colp)++;
1214 		break;
1215 
1216 	case VTAB:
1217 		if (tp->t_flags&VTDELAY) /* tty 37 */
1218 			c = 0177;
1219 		break;
1220 
1221 	case RETURN:
1222 		ctype = (tp->t_flags >> 12) & 03;
1223 		if (ctype == 1) /* tn 300 */
1224 			c = mstohz(83);
1225 		else if (ctype == 2) /* ti 700 */
1226 			c = mstohz(166);
1227 		else if (ctype == 3) { /* concept 100 */
1228 			int i;
1229 
1230 			if ((i = *colp) >= 0)
1231 				for (; i < 9; i++)
1232 					(void) putc(0177, &tp->t_outq);
1233 		}
1234 		*colp = 0;
1235 	}
1236 	if (c && (tp->t_lflag&FLUSHO) == 0)
1237 		(void) putc(c|0200, &tp->t_outq);
1238 	return (-1);
1239 }
1240 #undef mstohz
1241 
1242 /*
1243  * Called from device's read routine after it has
1244  * calculated the tty-structure given as argument.
1245  */
1246 ttread(tp, uio)
1247 	register struct tty *tp;
1248 	struct uio *uio;
1249 {
1250 	register struct clist *qp;
1251 	register int c, t_flags;
1252 	register long lflag = tp->t_lflag;
1253 	register long iflag = tp->t_iflag;
1254 	register u_char *cc = tp->t_cc;
1255 	int s, first, error = 0;
1256 
1257 
1258 loop:
1259 	/*
1260 	 * Take any pending input first.
1261 	 */
1262 	s = spltty();
1263 	if (tp->t_lflag&PENDIN)
1264 		ttypend(tp);
1265 	splx(s);
1266 
1267 	if ((tp->t_state&TS_CARR_ON)==0)
1268 		return (EIO);
1269 
1270 	/*
1271 	 * Hang process if it's in the background.
1272 	 */
1273 	if (tp == u.u_ttyp && u.u_procp->p_pgrp != tp->t_pgrp) {
1274 		if ((u.u_procp->p_sigignore & sigmask(SIGTTIN)) ||
1275 		   (u.u_procp->p_sigmask & sigmask(SIGTTIN)) ||
1276 		    u.u_procp->p_flag&SVFORK)
1277 			return (EIO);
1278 		gsignal(u.u_procp->p_pgrp, SIGTTIN);
1279 		sleep((caddr_t)&lbolt, TTIPRI);
1280 		goto loop;
1281 	}
1282 	t_flags = tp->t_flags;
1283 
1284 	/*
1285 	 * If canonical, use the canonical queue,
1286 	 * else use the raw queue.
1287 	 */
1288 	qp = lflag&ICANON ? &tp->t_canq : &tp->t_rawq;
1289 
1290 	/*
1291 	 * No input, sleep on rawq awaiting hardware
1292 	 * receipt and notification.
1293 	 */
1294 	s = spltty();
1295 	if (qp->c_cc <= 0) {
1296 		if ((tp->t_state&TS_CARR_ON) == 0 ||
1297 		    (tp->t_state&TS_NBIO)) {
1298 			splx(s);
1299 			return (EWOULDBLOCK);
1300 		}
1301 		sleep((caddr_t)&tp->t_rawq, TTIPRI);
1302 		splx(s);
1303 		goto loop;
1304 	}
1305 	splx(s);
1306 
1307 	/*
1308 	 * Input present, check for input mapping and processing.
1309 	 */
1310 	first = 1;
1311 	while ((c = getc(qp)) >= 0) {
1312 		/*
1313 		 * delayed suspend (^Y)
1314 		 */
1315 		if (CCEQ(cc[VDSUSP], c) && lflag&ISIG) {
1316 			gsignal(tp->t_pgrp, SIGTSTP);
1317 			if (first) {
1318 				sleep((caddr_t)&lbolt, TTIPRI);
1319 				goto loop;
1320 			}
1321 			break;
1322 		}
1323 		/*
1324 		 * Interpret EOF only in canonical mode.
1325 		 */
1326 		if (CCEQ(cc[VEOF], c) && lflag&ICANON)
1327 			break;
1328 		/*
1329 		 * Give user character.
1330 		 */
1331  		error = ureadc(iflag&ISTRIP ? c & 0177 : c , uio);
1332 		if (error)
1333 			break;
1334  		if (uio->uio_resid == 0)
1335 			break;
1336 		/*
1337 		 * In canonical mode check for a "break character"
1338 		 * marking the end of a "line of input".
1339 		 */
1340 		if (lflag&ICANON && ttbreakc(c)) {
1341 			break;
1342 		}
1343 		first = 0;
1344 	}
1345 
1346 checktandem:
1347 	/*
1348 	 * Look to unblock output now that (presumably)
1349 	 * the input queue has gone down.
1350 	 */
1351 	if (tp->t_state&TS_TBLOCK && tp->t_rawq.c_cc < TTYHOG/5) {
1352 		if (cc[VSTART] != POSIX_V_DISABLE
1353 		   && putc(cc[VSTART], &tp->t_outq) == 0) {
1354 			tp->t_state &= ~TS_TBLOCK;
1355 			ttstart(tp);
1356 		}
1357 	}
1358 	return (error);
1359 }
1360 
1361 /*
1362  * Check the output queue on tp for space for a kernel message
1363  * (from uprintf/tprintf).  Allow some space over the normal
1364  * hiwater mark so we don't lose messages due to normal flow
1365  * control, but don't let the tty run amok.
1366  * Sleeps here are not interruptible, but we return prematurely
1367  * if new signals come in.
1368  */
1369 ttycheckoutq(tp, wait)
1370 	register struct tty *tp;
1371 	int wait;
1372 {
1373 	int hiwat, s, oldsig;
1374 
1375 	hiwat = TTHIWAT(tp);
1376 	s = spltty();
1377 	oldsig = u.u_procp->p_sig;
1378 	if (tp->t_outq.c_cc > hiwat + 200)
1379 		while (tp->t_outq.c_cc > hiwat) {
1380 			ttstart(tp);
1381 			if (wait == 0 || u.u_procp->p_sig != oldsig) {
1382 				splx(s);
1383 				return (0);
1384 			}
1385 			timeout(wakeup, (caddr_t)&tp->t_outq, hz);
1386 			tp->t_state |= TS_ASLEEP;
1387 			sleep((caddr_t)&tp->t_outq, PZERO - 1);
1388 		}
1389 	splx(s);
1390 	return (1);
1391 }
1392 
1393 /*
1394  * Called from the device's write routine after it has
1395  * calculated the tty-structure given as argument.
1396  */
1397 ttwrite(tp, uio)
1398 	register struct tty *tp;
1399 	register struct uio *uio;
1400 {
1401 	register char *cp;
1402 	register int cc, ce, c;
1403 	int i, hiwat, cnt, error, s;
1404 	char obuf[OBUFSIZ];
1405 
1406 	hiwat = TTHIWAT(tp);
1407 	cnt = uio->uio_resid;
1408 	error = 0;
1409 loop:
1410 	if ((tp->t_state&TS_CARR_ON) == 0)
1411 		return (EIO);
1412 	/*
1413 	 * Hang the process if it's in the background.
1414 	 */
1415 	if (u.u_procp->p_pgrp != tp->t_pgrp && tp == u.u_ttyp &&
1416 	    (tp->t_lflag&TOSTOP) && (u.u_procp->p_flag&SVFORK)==0 &&
1417 	    !(u.u_procp->p_sigignore & sigmask(SIGTTOU)) &&
1418 	    !(u.u_procp->p_sigmask & sigmask(SIGTTOU))) {
1419 		gsignal(u.u_procp->p_pgrp, SIGTTOU);
1420 		sleep((caddr_t)&lbolt, TTIPRI);
1421 		goto loop;
1422 	}
1423 
1424 	/*
1425 	 * Process the user's data in at most OBUFSIZ
1426 	 * chunks.  Perform lower case simulation and
1427 	 * similar hacks.  Keep track of high water
1428 	 * mark, sleep on overflow awaiting device aid
1429 	 * in acquiring new space.
1430 	 */
1431 	while (uio->uio_resid > 0) {
1432 		if (tp->t_outq.c_cc > hiwat) {
1433 			cc = 0;
1434 			goto ovhiwat;
1435 		}
1436 		/*
1437 		 * Grab a hunk of data from the user.
1438 		 */
1439 		cc = uio->uio_iov->iov_len;
1440 		if (cc == 0) {
1441 			uio->uio_iovcnt--;
1442 			uio->uio_iov++;
1443 			if (uio->uio_iovcnt <= 0)
1444 				panic("ttwrite");
1445 			continue;
1446 		}
1447 		if (cc > OBUFSIZ)
1448 			cc = OBUFSIZ;
1449 		cp = obuf;
1450 		error = uiomove(cp, cc, UIO_WRITE, uio);
1451 		if (error)
1452 			break;
1453 		if (tp->t_lflag&FLUSHO)
1454 			continue;
1455 #ifdef notdef
1456 		/*
1457 		 * If we're mapping lower case or kludging tildes,
1458 		 * then we've got to look at each character, so
1459 		 * just feed the stuff to ttyoutput...
1460 		 */
1461 		if (tp->t_flags & (LCASE|TILDE)) {
1462 			while (cc > 0) {
1463 				c = *cp++;
1464 				tp->t_rocount = 0;
1465 				while ((c = ttyoutput(c, tp)) >= 0) {
1466 					/* out of clists, wait a bit */
1467 					ttstart(tp);
1468 					sleep((caddr_t)&lbolt, TTOPRI);
1469 					tp->t_rocount = 0;
1470 					if (cc != 0) {
1471 						uio->uio_iov->iov_base -= cc;
1472 						uio->uio_iov->iov_len += cc;
1473 						uio->uio_resid += cc;
1474 						uio->uio_offset -= cc;
1475 					}
1476 					goto loop;
1477 				}
1478 				--cc;
1479 				if (tp->t_outq.c_cc > hiwat)
1480 					goto ovhiwat;
1481 			}
1482 			continue;
1483 		}
1484 #endif
1485 		/*
1486 		 * If nothing fancy need be done, grab those characters we
1487 		 * can handle without any of ttyoutput's processing and
1488 		 * just transfer them to the output q.  For those chars
1489 		 * which require special processing (as indicated by the
1490 		 * bits in partab), call ttyoutput.  After processing
1491 		 * a hunk of data, look for FLUSHO so ^O's will take effect
1492 		 * immediately.
1493 		 */
1494 		while (cc > 0) {
1495 			if (!(tp->t_oflag&OPOST))
1496 				ce = cc;
1497 			else {
1498 				ce = cc - scanc((unsigned)cc, (caddr_t)cp,
1499 				   (caddr_t)partab, 077);
1500 				/*
1501 				 * If ce is zero, then we're processing
1502 				 * a special character through ttyoutput.
1503 				 */
1504 				if (ce == 0) {
1505 					tp->t_rocount = 0;
1506 					if (ttyoutput(*cp, tp) >= 0) {
1507 					    /* no c-lists, wait a bit */
1508 					    ttstart(tp);
1509 					    sleep((caddr_t)&lbolt, TTOPRI);
1510 					    if (cc != 0) {
1511 					        uio->uio_iov->iov_base -= cc;
1512 					        uio->uio_iov->iov_len += cc;
1513 					        uio->uio_resid += cc;
1514 						uio->uio_offset -= cc;
1515 					    }
1516 					    goto loop;
1517 					}
1518 					cp++, cc--;
1519 					if (tp->t_lflag&FLUSHO ||
1520 					    tp->t_outq.c_cc > hiwat)
1521 						goto ovhiwat;
1522 					continue;
1523 				}
1524 			}
1525 			/*
1526 			 * A bunch of normal characters have been found,
1527 			 * transfer them en masse to the output queue and
1528 			 * continue processing at the top of the loop.
1529 			 * If there are any further characters in this
1530 			 * <= OBUFSIZ chunk, the first should be a character
1531 			 * requiring special handling by ttyoutput.
1532 			 */
1533 			tp->t_rocount = 0;
1534 			i = b_to_q(cp, ce, &tp->t_outq);
1535 			ce -= i;
1536 			tp->t_col += ce;
1537 			cp += ce, cc -= ce, tk_nout += ce;
1538 			if (i > 0) {
1539 				/* out of c-lists, wait a bit */
1540 				ttstart(tp);
1541 				sleep((caddr_t)&lbolt, TTOPRI);
1542 				uio->uio_iov->iov_base -= cc;
1543 				uio->uio_iov->iov_len += cc;
1544 				uio->uio_resid += cc;
1545 				uio->uio_offset -= cc;
1546 				goto loop;
1547 			}
1548 			if (tp->t_lflag&FLUSHO || tp->t_outq.c_cc > hiwat)
1549 				goto ovhiwat;
1550 		}
1551 		ttstart(tp);
1552 	}
1553 	return (error);
1554 
1555 ovhiwat:
1556 	if (cc != 0) {
1557 		uio->uio_iov->iov_base -= cc;
1558 		uio->uio_iov->iov_len += cc;
1559 		uio->uio_resid += cc;
1560 		uio->uio_offset -= cc;
1561 	}
1562 	ttstart(tp);
1563 	s = spltty();
1564 	/*
1565 	 * This can only occur if FLUSHO is set in t_lflag,
1566 	 * or if ttstart/oproc is synchronous (or very fast).
1567 	 */
1568 	if (tp->t_outq.c_cc <= hiwat) {
1569 		splx(s);
1570 		goto loop;
1571 	}
1572 	if (tp->t_state&TS_NBIO) {
1573 		splx(s);
1574 		if (uio->uio_resid == cnt)
1575 			return (EWOULDBLOCK);
1576 		return (0);
1577 	}
1578 	tp->t_state |= TS_ASLEEP;
1579 	sleep((caddr_t)&tp->t_outq, TTOPRI);
1580 	splx(s);
1581 	goto loop;
1582 }
1583 
1584 /*
1585  * Rubout one character from the rawq of tp
1586  * as cleanly as possible.
1587  */
1588 ttyrub(c, tp)
1589 	register c;
1590 	register struct tty *tp;
1591 {
1592 	register char *cp;
1593 	register int savecol;
1594 	int s;
1595 	char *nextc();
1596 
1597 	if ((tp->t_lflag&ECHO) == 0)
1598 		return;
1599 	tp->t_lflag &= ~FLUSHO;
1600 	c &= 0377;
1601 	if (tp->t_lflag&ECHOE) {
1602 		if (tp->t_rocount == 0) {
1603 			/*
1604 			 * Screwed by ttwrite; retype
1605 			 */
1606 			ttyretype(tp);
1607 			return;
1608 		}
1609 		/* if tab or newline was escaped  - XXX - not 8bit */
1610 		if (c == ('\t'|0200) || c == ('\n'|0200))
1611 			ttyrubo(tp, 2);
1612 		else switch (partab[c&=0177]&0177) {
1613 
1614 		case ORDINARY:
1615 #ifdef notdef
1616 			if (tp->t_flags&LCASE && c >= 'A' && c <= 'Z')
1617 				ttyrubo(tp, 2);
1618 			else
1619 #endif
1620 				ttyrubo(tp, 1);
1621 			break;
1622 
1623 		case VTAB:
1624 		case BACKSPACE:
1625 		case CONTROL:
1626 		case RETURN:
1627 			if (tp->t_lflag&ECHOCTL)
1628 				ttyrubo(tp, 2);
1629 			break;
1630 
1631 		case TAB:
1632 			if (tp->t_rocount < tp->t_rawq.c_cc) {
1633 				ttyretype(tp);
1634 				return;
1635 			}
1636 			s = spltty();
1637 			savecol = tp->t_col;
1638 			tp->t_state |= TS_CNTTB;
1639 			tp->t_lflag |= FLUSHO;
1640 			tp->t_col = tp->t_rocol;
1641 			cp = tp->t_rawq.c_cf;
1642 			for (; cp; cp = nextc(&tp->t_rawq, cp))
1643 				ttyecho(*cp, tp);
1644 			tp->t_lflag &= ~FLUSHO;
1645 			tp->t_state &= ~TS_CNTTB;
1646 			splx(s);
1647 			/*
1648 			 * savecol will now be length of the tab
1649 			 */
1650 			savecol -= tp->t_col;
1651 			tp->t_col += savecol;
1652 			if (savecol > 8)
1653 				savecol = 8;		/* overflow screw */
1654 			while (--savecol >= 0)
1655 				(void) ttyoutput('\b', tp);
1656 			break;
1657 
1658 		default:
1659 			panic("ttyrub");
1660 		}
1661 	} else if (tp->t_lflag&ECHOPRT) {
1662 		if ((tp->t_state&TS_ERASE) == 0) {
1663 			(void) ttyoutput('\\', tp);
1664 			tp->t_state |= TS_ERASE;
1665 		}
1666 		ttyecho(c, tp);
1667 	} else
1668 		ttyecho(tp->t_cc[VERASE], tp);
1669 	tp->t_rocount--;
1670 }
1671 
1672 /*
1673  * Crt back over cnt chars perhaps
1674  * erasing them.
1675  */
1676 ttyrubo(tp, cnt)
1677 	register struct tty *tp;
1678 	int cnt;
1679 {
1680 	register char *rubostring = tp->t_lflag&ECHOE ? "\b \b" : "\b";
1681 
1682 	while (--cnt >= 0)
1683 		ttyout(rubostring, tp);
1684 }
1685 
1686 /*
1687  * Reprint the rawq line.
1688  * We assume c_cc has already been checked.
1689  */
1690 ttyretype(tp)
1691 	register struct tty *tp;
1692 {
1693 	register char *cp;
1694 	char *nextc();
1695 	int s;
1696 
1697 	if (tp->t_cc[VREPRINT] != POSIX_V_DISABLE)
1698 		ttyecho(tp->t_cc[VREPRINT], tp);
1699 	(void) ttyoutput('\n', tp);
1700 	s = spltty();
1701 	for (cp = tp->t_canq.c_cf; cp; cp = nextc(&tp->t_canq, cp))
1702 		ttyecho(*cp, tp);
1703 	for (cp = tp->t_rawq.c_cf; cp; cp = nextc(&tp->t_rawq, cp))
1704 		ttyecho(*cp, tp);
1705 	tp->t_state &= ~TS_ERASE;
1706 	splx(s);
1707 	tp->t_rocount = tp->t_rawq.c_cc;
1708 	tp->t_rocol = 0;
1709 }
1710 
1711 /*
1712  * Echo a typed character to the terminal.
1713  */
1714 ttyecho(c, tp)
1715 	register c;
1716 	register struct tty *tp;
1717 {
1718 
1719 	c &= 0377;
1720 	if ((tp->t_state&TS_CNTTB) == 0)
1721 		tp->t_lflag &= ~FLUSHO;
1722 	if ((tp->t_lflag&ECHO) == 0 && !(tp->t_lflag&ECHONL && c == '\n'))
1723 		return;
1724 	if (tp->t_lflag&ECHOCTL) {
1725 		if ((c&0177) <= 037 && c!='\t' && c!='\n' || (c&0177)==0177) {
1726 			(void) ttyoutput('^', tp);
1727 			c &= 0177;
1728 			if (c == 0177)
1729 				c = '?';
1730 #ifdef notdef
1731 			else if (tp->t_flags&LCASE)
1732 				c += 'a' - 1;
1733 #endif
1734 			else
1735 				c += 'A' - 1;
1736 		}
1737 	}
1738 	(void) ttyoutput(c&0177, tp);
1739 }
1740 
1741 /*
1742  * send string cp to tp
1743  */
1744 ttyout(cp, tp)
1745 	register char *cp;
1746 	register struct tty *tp;
1747 {
1748 	register char c;
1749 
1750 	while (c = *cp++)
1751 		(void) ttyoutput(c, tp);
1752 }
1753 
1754 ttwakeup(tp)
1755 	struct tty *tp;
1756 {
1757 
1758 	if (tp->t_rsel) {
1759 		selwakeup(tp->t_rsel, tp->t_state&TS_RCOLL);
1760 		tp->t_state &= ~TS_RCOLL;
1761 		tp->t_rsel = 0;
1762 	}
1763 	if (tp->t_state & TS_ASYNC)
1764 		gsignal(tp->t_pgrp, SIGIO);
1765 	wakeup((caddr_t)&tp->t_rawq);
1766 }
1767