tty.c revision 1549
1/*-
2 * Copyright (c) 1982, 1986, 1990, 1991, 1993
3 *	The Regents of the University of California.  All rights reserved.
4 * (c) UNIX System Laboratories, Inc.
5 * All or some portions of this file are derived from material licensed
6 * to the University of California by American Telephone and Telegraph
7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8 * the permission of UNIX System Laboratories, Inc.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 *    notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 *    notice, this list of conditions and the following disclaimer in the
17 *    documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 *    must display the following acknowledgement:
20 *	This product includes software developed by the University of
21 *	California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 *    may be used to endorse or promote products derived from this software
24 *    without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 *	@(#)tty.c	8.8 (Berkeley) 1/21/94
39 */
40
41#include <sys/param.h>
42#include <sys/systm.h>
43#include <sys/ioctl.h>
44#include <sys/proc.h>
45#define	TTYDEFCHARS
46#include <sys/tty.h>
47#undef	TTYDEFCHARS
48#include <sys/file.h>
49#include <sys/conf.h>
50#include <sys/dkstat.h>
51#include <sys/uio.h>
52#include <sys/kernel.h>
53#include <sys/vnode.h>
54#include <sys/syslog.h>
55
56#include <vm/vm.h>
57
58static int	proc_compare __P((struct proc *p1, struct proc *p2));
59static int	ttnread __P((struct tty *));
60static void	ttyblock __P((struct tty *tp));
61static void	ttyecho __P((int, struct tty *tp));
62static void	ttyrubo __P((struct tty *, int));
63
64/* Symbolic sleep message strings. */
65char ttclos[]	= "ttycls";
66char ttopen[]	= "ttyopn";
67char ttybg[]	= "ttybg";
68char ttybuf[]	= "ttybuf";
69char ttyin[]	= "ttyin";
70char ttyout[]	= "ttyout";
71
72/*
73 * Table with character classes and parity. The 8th bit indicates parity,
74 * the 7th bit indicates the character is an alphameric or underscore (for
75 * ALTWERASE), and the low 6 bits indicate delay type.  If the low 6 bits
76 * are 0 then the character needs no special processing on output; classes
77 * other than 0 might be translated or (not currently) require delays.
78 */
79#define	E	0x00	/* Even parity. */
80#define	O	0x80	/* Odd parity. */
81#define	PARITY(c)	(char_type[c] & O)
82
83#define	ALPHA	0x40	/* Alpha or underscore. */
84#define	ISALPHA(c)	(char_type[(c) & TTY_CHARMASK] & ALPHA)
85
86#define	CCLASSMASK	0x3f
87#define	CCLASS(c)	(char_type[c] & CCLASSMASK)
88
89#define	BS	BACKSPACE
90#define	CC	CONTROL
91#define	CR	RETURN
92#define	NA	ORDINARY | ALPHA
93#define	NL	NEWLINE
94#define	NO	ORDINARY
95#define	TB	TAB
96#define	VT	VTAB
97
98char const char_type[] = {
99	E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC,	/* nul - bel */
100	O|BS, E|TB, E|NL, O|CC, E|VT, O|CR, O|CC, E|CC, /* bs - si */
101	O|CC, E|CC, E|CC, O|CC, E|CC, O|CC, O|CC, E|CC, /* dle - etb */
102	E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC, /* can - us */
103	O|NO, E|NO, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* sp - ' */
104	E|NO, O|NO, O|NO, E|NO, O|NO, E|NO, E|NO, O|NO, /* ( - / */
105	E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* 0 - 7 */
106	O|NA, E|NA, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* 8 - ? */
107	O|NO, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* @ - G */
108	E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* H - O */
109	E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* P - W */
110	O|NA, E|NA, E|NA, O|NO, E|NO, O|NO, O|NO, O|NA, /* X - _ */
111	E|NO, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* ` - g */
112	O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* h - o */
113	O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* p - w */
114	E|NA, O|NA, O|NA, E|NO, O|NO, E|NO, E|NO, O|CC, /* x - del */
115	/*
116	 * Meta chars; should be settable per character set;
117	 * for now, treat them all as normal characters.
118	 */
119	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
120	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
121	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
122	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
123	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
124	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
125	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
126	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
127	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
128	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
129	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
130	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
131	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
132	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
133	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
134	NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
135};
136#undef	BS
137#undef	CC
138#undef	CR
139#undef	NA
140#undef	NL
141#undef	NO
142#undef	TB
143#undef	VT
144
145/* Macros to clear/set/test flags. */
146#define	SET(t, f)	(t) |= (f)
147#define	CLR(t, f)	(t) &= ~(f)
148#define	ISSET(t, f)	((t) & (f))
149
150/*
151 * Initial open of tty, or (re)entry to standard tty line discipline.
152 */
153int
154ttyopen(device, tp)
155	dev_t device;
156	register struct tty *tp;
157{
158	int s;
159
160	s = spltty();
161	tp->t_dev = device;
162	if (!ISSET(tp->t_state, TS_ISOPEN)) {
163		SET(tp->t_state, TS_ISOPEN);
164		bzero(&tp->t_winsize, sizeof(tp->t_winsize));
165	}
166	CLR(tp->t_state, TS_WOPEN);
167	splx(s);
168	return (0);
169}
170
171/*
172 * Handle close() on a tty line: flush and set to initial state,
173 * bumping generation number so that pending read/write calls
174 * can detect recycling of the tty.
175 */
176int
177ttyclose(tp)
178	register struct tty *tp;
179{
180	extern struct tty *constty;	/* Temporary virtual console. */
181
182	if (constty == tp)
183		constty = NULL;
184
185	ttyflush(tp, FREAD | FWRITE);
186
187	tp->t_gen++;
188	tp->t_pgrp = NULL;
189	tp->t_session = NULL;
190	tp->t_state = 0;
191	return (0);
192}
193
194#define	FLUSHQ(q) {							\
195	if ((q)->c_cc)							\
196		ndflush(q, (q)->c_cc);					\
197}
198
199/* Is 'c' a line delimiter ("break" character)? */
200#define	TTBREAKC(c)							\
201	((c) == '\n' || ((c) == cc[VEOF] ||				\
202	(c) == cc[VEOL] || (c) == cc[VEOL2]) && (c) != _POSIX_VDISABLE)
203
204
205/*
206 * Process input of a single character received on a tty.
207 */
208int
209ttyinput(c, tp)
210	register int c;
211	register struct tty *tp;
212{
213	register int iflag, lflag;
214	register u_char *cc;
215	int i, err;
216
217	/*
218	 * If input is pending take it first.
219	 */
220	lflag = tp->t_lflag;
221	if (ISSET(lflag, PENDIN))
222		ttypend(tp);
223	/*
224	 * Gather stats.
225	 */
226	if (ISSET(lflag, ICANON)) {
227		++tk_cancc;
228		++tp->t_cancc;
229	} else {
230		++tk_rawcc;
231		++tp->t_rawcc;
232	}
233	++tk_nin;
234
235	/* Handle exceptional conditions (break, parity, framing). */
236	cc = tp->t_cc;
237	iflag = tp->t_iflag;
238	if (err = (ISSET(c, TTY_ERRORMASK))) {
239		CLR(c, TTY_ERRORMASK);
240		if (ISSET(err, TTY_FE) && !c) {	/* Break. */
241			if (ISSET(iflag, IGNBRK))
242				goto endcase;
243			else if (ISSET(iflag, BRKINT) &&
244			    ISSET(lflag, ISIG) &&
245			    (cc[VINTR] != _POSIX_VDISABLE))
246				c = cc[VINTR];
247			else if (ISSET(iflag, PARMRK))
248				goto parmrk;
249		} else if (ISSET(err, TTY_PE) &&
250		    ISSET(iflag, INPCK) || ISSET(err, TTY_FE)) {
251			if (ISSET(iflag, IGNPAR))
252				goto endcase;
253			else if (ISSET(iflag, PARMRK)) {
254parmrk:				(void)putc(0377 | TTY_QUOTE, &tp->t_rawq);
255				(void)putc(0 | TTY_QUOTE, &tp->t_rawq);
256				(void)putc(c | TTY_QUOTE, &tp->t_rawq);
257				goto endcase;
258			} else
259				c = 0;
260		}
261	}
262	/*
263	 * In tandem mode, check high water mark.
264	 */
265	if (ISSET(iflag, IXOFF))
266		ttyblock(tp);
267	if (!ISSET(tp->t_state, TS_TYPEN) && ISSET(iflag, ISTRIP))
268		CLR(c, 0x80);
269	if (!ISSET(lflag, EXTPROC)) {
270		/*
271		 * Check for literal nexting very first
272		 */
273		if (ISSET(tp->t_state, TS_LNCH)) {
274			SET(c, TTY_QUOTE);
275			CLR(tp->t_state, TS_LNCH);
276		}
277		/*
278		 * Scan for special characters.  This code
279		 * is really just a big case statement with
280		 * non-constant cases.  The bottom of the
281		 * case statement is labeled ``endcase'', so goto
282		 * it after a case match, or similar.
283		 */
284
285		/*
286		 * Control chars which aren't controlled
287		 * by ICANON, ISIG, or IXON.
288		 */
289		if (ISSET(lflag, IEXTEN)) {
290			if (CCEQ(cc[VLNEXT], c)) {
291				if (ISSET(lflag, ECHO)) {
292					if (ISSET(lflag, ECHOE)) {
293						(void)ttyoutput('^', tp);
294						(void)ttyoutput('\b', tp);
295					} else
296						ttyecho(c, tp);
297				}
298				SET(tp->t_state, TS_LNCH);
299				goto endcase;
300			}
301			if (CCEQ(cc[VDISCARD], c)) {
302				if (ISSET(lflag, FLUSHO))
303					CLR(tp->t_lflag, FLUSHO);
304				else {
305					ttyflush(tp, FWRITE);
306					ttyecho(c, tp);
307					if (tp->t_rawq.c_cc + tp->t_canq.c_cc)
308						ttyretype(tp);
309					SET(tp->t_lflag, FLUSHO);
310				}
311				goto startoutput;
312			}
313		}
314		/*
315		 * Signals.
316		 */
317		if (ISSET(lflag, ISIG)) {
318			if (CCEQ(cc[VINTR], c) || CCEQ(cc[VQUIT], c)) {
319				if (!ISSET(lflag, NOFLSH))
320					ttyflush(tp, FREAD | FWRITE);
321				ttyecho(c, tp);
322				pgsignal(tp->t_pgrp,
323				    CCEQ(cc[VINTR], c) ? SIGINT : SIGQUIT, 1);
324				goto endcase;
325			}
326			if (CCEQ(cc[VSUSP], c)) {
327				if (!ISSET(lflag, NOFLSH))
328					ttyflush(tp, FREAD);
329				ttyecho(c, tp);
330				pgsignal(tp->t_pgrp, SIGTSTP, 1);
331				goto endcase;
332			}
333		}
334		/*
335		 * Handle start/stop characters.
336		 */
337		if (ISSET(iflag, IXON)) {
338			if (CCEQ(cc[VSTOP], c)) {
339				if (!ISSET(tp->t_state, TS_TTSTOP)) {
340					SET(tp->t_state, TS_TTSTOP);
341#ifdef sun4c						/* XXX */
342					(*tp->t_stop)(tp, 0);
343#else
344					(*cdevsw[major(tp->t_dev)].d_stop)(tp,
345					   0);
346#endif
347					return (0);
348				}
349				if (!CCEQ(cc[VSTART], c))
350					return (0);
351				/*
352				 * if VSTART == VSTOP then toggle
353				 */
354				goto endcase;
355			}
356			if (CCEQ(cc[VSTART], c))
357				goto restartoutput;
358		}
359		/*
360		 * IGNCR, ICRNL, & INLCR
361		 */
362		if (c == '\r') {
363			if (ISSET(iflag, IGNCR))
364				goto endcase;
365			else if (ISSET(iflag, ICRNL))
366				c = '\n';
367		} else if (c == '\n' && ISSET(iflag, INLCR))
368			c = '\r';
369	}
370	if (!ISSET(tp->t_lflag, EXTPROC) && ISSET(lflag, ICANON)) {
371		/*
372		 * From here on down canonical mode character
373		 * processing takes place.
374		 */
375		/*
376		 * erase (^H / ^?)
377		 */
378		if (CCEQ(cc[VERASE], c)) {
379			if (tp->t_rawq.c_cc)
380				ttyrub(unputc(&tp->t_rawq), tp);
381			goto endcase;
382		}
383		/*
384		 * kill (^U)
385		 */
386		if (CCEQ(cc[VKILL], c)) {
387			if (ISSET(lflag, ECHOKE) &&
388			    tp->t_rawq.c_cc == tp->t_rocount &&
389			    !ISSET(lflag, ECHOPRT))
390				while (tp->t_rawq.c_cc)
391					ttyrub(unputc(&tp->t_rawq), tp);
392			else {
393				ttyecho(c, tp);
394				if (ISSET(lflag, ECHOK) ||
395				    ISSET(lflag, ECHOKE))
396					ttyecho('\n', tp);
397				FLUSHQ(&tp->t_rawq);
398				tp->t_rocount = 0;
399			}
400			CLR(tp->t_state, TS_LOCAL);
401			goto endcase;
402		}
403		/*
404		 * word erase (^W)
405		 */
406		if (CCEQ(cc[VWERASE], c)) {
407			int alt = ISSET(lflag, ALTWERASE);
408			int ctype;
409
410			/*
411			 * erase whitespace
412			 */
413			while ((c = unputc(&tp->t_rawq)) == ' ' || c == '\t')
414				ttyrub(c, tp);
415			if (c == -1)
416				goto endcase;
417			/*
418			 * erase last char of word and remember the
419			 * next chars type (for ALTWERASE)
420			 */
421			ttyrub(c, tp);
422			c = unputc(&tp->t_rawq);
423			if (c == -1)
424				goto endcase;
425			if (c == ' ' || c == '\t') {
426				(void)putc(c, &tp->t_rawq);
427				goto endcase;
428			}
429			ctype = ISALPHA(c);
430			/*
431			 * erase rest of word
432			 */
433			do {
434				ttyrub(c, tp);
435				c = unputc(&tp->t_rawq);
436				if (c == -1)
437					goto endcase;
438			} while (c != ' ' && c != '\t' &&
439			    (alt == 0 || ISALPHA(c) == ctype));
440			(void)putc(c, &tp->t_rawq);
441			goto endcase;
442		}
443		/*
444		 * reprint line (^R)
445		 */
446		if (CCEQ(cc[VREPRINT], c)) {
447			ttyretype(tp);
448			goto endcase;
449		}
450		/*
451		 * ^T - kernel info and generate SIGINFO
452		 */
453		if (CCEQ(cc[VSTATUS], c)) {
454			if (ISSET(lflag, ISIG))
455				pgsignal(tp->t_pgrp, SIGINFO, 1);
456			if (!ISSET(lflag, NOKERNINFO))
457				ttyinfo(tp);
458			goto endcase;
459		}
460	}
461	/*
462	 * Check for input buffer overflow
463	 */
464	if (tp->t_rawq.c_cc + tp->t_canq.c_cc >= TTYHOG) {
465		if (ISSET(iflag, IMAXBEL)) {
466			if (tp->t_outq.c_cc < tp->t_hiwat)
467				(void)ttyoutput(CTRL('g'), tp);
468		} else
469			ttyflush(tp, FREAD | FWRITE);
470		goto endcase;
471	}
472	/*
473	 * Put data char in q for user and
474	 * wakeup on seeing a line delimiter.
475	 */
476	if (putc(c, &tp->t_rawq) >= 0) {
477		if (!ISSET(lflag, ICANON)) {
478			ttwakeup(tp);
479			ttyecho(c, tp);
480			goto endcase;
481		}
482		if (TTBREAKC(c)) {
483			tp->t_rocount = 0;
484			catq(&tp->t_rawq, &tp->t_canq);
485			ttwakeup(tp);
486		} else if (tp->t_rocount++ == 0)
487			tp->t_rocol = tp->t_column;
488		if (ISSET(tp->t_state, TS_ERASE)) {
489			/*
490			 * end of prterase \.../
491			 */
492			CLR(tp->t_state, TS_ERASE);
493			(void)ttyoutput('/', tp);
494		}
495		i = tp->t_column;
496		ttyecho(c, tp);
497		if (CCEQ(cc[VEOF], c) && ISSET(lflag, ECHO)) {
498			/*
499			 * Place the cursor over the '^' of the ^D.
500			 */
501			i = min(2, tp->t_column - i);
502			while (i > 0) {
503				(void)ttyoutput('\b', tp);
504				i--;
505			}
506		}
507	}
508endcase:
509	/*
510	 * IXANY means allow any character to restart output.
511	 */
512	if (ISSET(tp->t_state, TS_TTSTOP) &&
513	    !ISSET(iflag, IXANY) && cc[VSTART] != cc[VSTOP])
514		return (0);
515restartoutput:
516	CLR(tp->t_lflag, FLUSHO);
517	CLR(tp->t_state, TS_TTSTOP);
518startoutput:
519	return (ttstart(tp));
520}
521
522/*
523 * Output a single character on a tty, doing output processing
524 * as needed (expanding tabs, newline processing, etc.).
525 * Returns < 0 if succeeds, otherwise returns char to resend.
526 * Must be recursive.
527 */
528int
529ttyoutput(c, tp)
530	register int c;
531	register struct tty *tp;
532{
533	register long oflag;
534	register int col, s;
535
536	oflag = tp->t_oflag;
537	if (!ISSET(oflag, OPOST)) {
538		if (ISSET(tp->t_lflag, FLUSHO))
539			return (-1);
540		if (putc(c, &tp->t_outq))
541			return (c);
542		tk_nout++;
543		tp->t_outcc++;
544		return (-1);
545	}
546	/*
547	 * Do tab expansion if OXTABS is set.  Special case if we external
548	 * processing, we don't do the tab expansion because we'll probably
549	 * get it wrong.  If tab expansion needs to be done, let it happen
550	 * externally.
551	 */
552	CLR(c, ~TTY_CHARMASK);
553	if (c == '\t' &&
554	    ISSET(oflag, OXTABS) && !ISSET(tp->t_lflag, EXTPROC)) {
555		c = 8 - (tp->t_column & 7);
556		if (!ISSET(tp->t_lflag, FLUSHO)) {
557			s = spltty();		/* Don't interrupt tabs. */
558			c -= b_to_q("        ", c, &tp->t_outq);
559			tk_nout += c;
560			tp->t_outcc += c;
561			splx(s);
562		}
563		tp->t_column += c;
564		return (c ? -1 : '\t');
565	}
566	if (c == CEOT && ISSET(oflag, ONOEOT))
567		return (-1);
568
569	/*
570	 * Newline translation: if ONLCR is set,
571	 * translate newline into "\r\n".
572	 */
573	if (c == '\n' && ISSET(tp->t_oflag, ONLCR)) {
574		tk_nout++;
575		tp->t_outcc++;
576		if (putc('\r', &tp->t_outq))
577			return (c);
578	}
579	tk_nout++;
580	tp->t_outcc++;
581	if (!ISSET(tp->t_lflag, FLUSHO) && putc(c, &tp->t_outq))
582		return (c);
583
584	col = tp->t_column;
585	switch (CCLASS(c)) {
586	case BACKSPACE:
587		if (col > 0)
588			--col;
589		break;
590	case CONTROL:
591		break;
592	case NEWLINE:
593	case RETURN:
594		col = 0;
595		break;
596	case ORDINARY:
597		++col;
598		break;
599	case TAB:
600		col = (col + 8) & ~7;
601		break;
602	}
603	tp->t_column = col;
604	return (-1);
605}
606
607/*
608 * Ioctls for all tty devices.  Called after line-discipline specific ioctl
609 * has been called to do discipline-specific functions and/or reject any
610 * of these ioctl commands.
611 */
612/* ARGSUSED */
613int
614ttioctl(tp, cmd, data, flag)
615	register struct tty *tp;
616	int cmd, flag;
617	void *data;
618{
619	extern struct tty *constty;	/* Temporary virtual console. */
620	extern int nlinesw;
621	register struct proc *p;
622	int s, error;
623
624	p = curproc;			/* XXX */
625
626	/* If the ioctl involves modification, hang if in the background. */
627	switch (cmd) {
628	case  TIOCFLUSH:
629	case  TIOCSETA:
630	case  TIOCSETD:
631	case  TIOCSETAF:
632	case  TIOCSETAW:
633#ifdef notdef
634	case  TIOCSPGRP:
635#endif
636	case  TIOCSTI:
637	case  TIOCSWINSZ:
638#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
639	case  TIOCLBIC:
640	case  TIOCLBIS:
641	case  TIOCLSET:
642	case  TIOCSETC:
643	case OTIOCSETD:
644	case  TIOCSETN:
645	case  TIOCSETP:
646	case  TIOCSLTC:
647#endif
648		while (isbackground(curproc, tp) &&
649		    p->p_pgrp->pg_jobc && (p->p_flag & P_PPWAIT) == 0 &&
650		    (p->p_sigignore & sigmask(SIGTTOU)) == 0 &&
651		    (p->p_sigmask & sigmask(SIGTTOU)) == 0) {
652			pgsignal(p->p_pgrp, SIGTTOU, 1);
653			if (error = ttysleep(tp,
654			    &lbolt, TTOPRI | PCATCH, ttybg, 0))
655				return (error);
656		}
657		break;
658	}
659
660	switch (cmd) {			/* Process the ioctl. */
661	case FIOASYNC:			/* set/clear async i/o */
662		s = spltty();
663		if (*(int *)data)
664			SET(tp->t_state, TS_ASYNC);
665		else
666			CLR(tp->t_state, TS_ASYNC);
667		splx(s);
668		break;
669	case FIONBIO:			/* set/clear non-blocking i/o */
670		break;			/* XXX: delete. */
671	case FIONREAD:			/* get # bytes to read */
672		*(int *)data = ttnread(tp);
673		break;
674	case TIOCEXCL:			/* set exclusive use of tty */
675		s = spltty();
676		SET(tp->t_state, TS_XCLUDE);
677		splx(s);
678		break;
679	case TIOCFLUSH: {		/* flush buffers */
680		register int flags = *(int *)data;
681
682		if (flags == 0)
683			flags = FREAD | FWRITE;
684		else
685			flags &= FREAD | FWRITE;
686		ttyflush(tp, flags);
687		break;
688	}
689	case TIOCCONS:			/* become virtual console */
690		if (*(int *)data) {
691			if (constty && constty != tp &&
692			    ISSET(constty->t_state, TS_CARR_ON | TS_ISOPEN) ==
693			    (TS_CARR_ON | TS_ISOPEN))
694				return (EBUSY);
695#ifndef	UCONSOLE
696			if (error = suser(p->p_ucred, &p->p_acflag))
697				return (error);
698#endif
699			constty = tp;
700		} else if (tp == constty)
701			constty = NULL;
702		break;
703	case TIOCDRAIN:			/* wait till output drained */
704		if (error = ttywait(tp))
705			return (error);
706		break;
707	case TIOCGETA: {		/* get termios struct */
708		struct termios *t = (struct termios *)data;
709
710		bcopy(&tp->t_termios, t, sizeof(struct termios));
711		break;
712	}
713	case TIOCGETD:			/* get line discipline */
714		*(int *)data = tp->t_line;
715		break;
716	case TIOCGWINSZ:		/* get window size */
717		*(struct winsize *)data = tp->t_winsize;
718		break;
719	case TIOCGPGRP:			/* get pgrp of tty */
720		if (!isctty(p, tp))
721			return (ENOTTY);
722		*(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
723		break;
724#ifdef TIOCHPCL
725	case TIOCHPCL:			/* hang up on last close */
726		s = spltty();
727		SET(tp->t_cflag, HUPCL);
728		splx(s);
729		break;
730#endif
731	case TIOCNXCL:			/* reset exclusive use of tty */
732		s = spltty();
733		CLR(tp->t_state, TS_XCLUDE);
734		splx(s);
735		break;
736	case TIOCOUTQ:			/* output queue size */
737		*(int *)data = tp->t_outq.c_cc;
738		break;
739	case TIOCSETA:			/* set termios struct */
740	case TIOCSETAW:			/* drain output, set */
741	case TIOCSETAF: {		/* drn out, fls in, set */
742		register struct termios *t = (struct termios *)data;
743
744		s = spltty();
745		if (cmd == TIOCSETAW || cmd == TIOCSETAF) {
746			if (error = ttywait(tp)) {
747				splx(s);
748				return (error);
749			}
750			if (cmd == TIOCSETAF)
751				ttyflush(tp, FREAD);
752		}
753		if (!ISSET(t->c_cflag, CIGNORE)) {
754			/*
755			 * Set device hardware.
756			 */
757			if (tp->t_param && (error = (*tp->t_param)(tp, t))) {
758				splx(s);
759				return (error);
760			} else {
761				if (!ISSET(tp->t_state, TS_CARR_ON) &&
762				    ISSET(tp->t_cflag, CLOCAL) &&
763				    !ISSET(t->c_cflag, CLOCAL)) {
764					CLR(tp->t_state, TS_ISOPEN);
765					SET(tp->t_state, TS_WOPEN);
766					ttwakeup(tp);
767				}
768				tp->t_cflag = t->c_cflag;
769				tp->t_ispeed = t->c_ispeed;
770				tp->t_ospeed = t->c_ospeed;
771			}
772			ttsetwater(tp);
773		}
774		if (cmd != TIOCSETAF) {
775			if (ISSET(t->c_lflag, ICANON) !=
776			    ISSET(tp->t_lflag, ICANON))
777				if (ISSET(t->c_lflag, ICANON)) {
778					SET(tp->t_lflag, PENDIN);
779					ttwakeup(tp);
780				} else {
781					struct clist tq;
782
783					catq(&tp->t_rawq, &tp->t_canq);
784					tq = tp->t_rawq;
785					tp->t_rawq = tp->t_canq;
786					tp->t_canq = tq;
787					CLR(tp->t_lflag, PENDIN);
788				}
789		}
790		tp->t_iflag = t->c_iflag;
791		tp->t_oflag = t->c_oflag;
792		/*
793		 * Make the EXTPROC bit read only.
794		 */
795		if (ISSET(tp->t_lflag, EXTPROC))
796			SET(t->c_lflag, EXTPROC);
797		else
798			CLR(t->c_lflag, EXTPROC);
799		tp->t_lflag = t->c_lflag | ISSET(tp->t_lflag, PENDIN);
800		bcopy(t->c_cc, tp->t_cc, sizeof(t->c_cc));
801		splx(s);
802		break;
803	}
804	case TIOCSETD: {		/* set line discipline */
805		register int t = *(int *)data;
806		dev_t device = tp->t_dev;
807
808		if ((u_int)t >= nlinesw)
809			return (ENXIO);
810		if (t != tp->t_line) {
811			s = spltty();
812			(*linesw[tp->t_line].l_close)(tp, flag);
813			error = (*linesw[t].l_open)(device, tp);
814			if (error) {
815				(void)(*linesw[tp->t_line].l_open)(device, tp);
816				splx(s);
817				return (error);
818			}
819			tp->t_line = t;
820			splx(s);
821		}
822		break;
823	}
824	case TIOCSTART:			/* start output, like ^Q */
825		s = spltty();
826		if (ISSET(tp->t_state, TS_TTSTOP) ||
827		    ISSET(tp->t_lflag, FLUSHO)) {
828			CLR(tp->t_lflag, FLUSHO);
829			CLR(tp->t_state, TS_TTSTOP);
830			ttstart(tp);
831		}
832		splx(s);
833		break;
834	case TIOCSTI:			/* simulate terminal input */
835		if (p->p_ucred->cr_uid && (flag & FREAD) == 0)
836			return (EPERM);
837		if (p->p_ucred->cr_uid && !isctty(p, tp))
838			return (EACCES);
839		(*linesw[tp->t_line].l_rint)(*(u_char *)data, tp);
840		break;
841	case TIOCSTOP:			/* stop output, like ^S */
842		s = spltty();
843		if (!ISSET(tp->t_state, TS_TTSTOP)) {
844			SET(tp->t_state, TS_TTSTOP);
845#ifdef sun4c				/* XXX */
846			(*tp->t_stop)(tp, 0);
847#else
848			(*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
849#endif
850		}
851		splx(s);
852		break;
853	case TIOCSCTTY:			/* become controlling tty */
854		/* Session ctty vnode pointer set in vnode layer. */
855		if (!SESS_LEADER(p) ||
856		    (p->p_session->s_ttyvp || tp->t_session) &&
857		    (tp->t_session != p->p_session))
858			return (EPERM);
859		tp->t_session = p->p_session;
860		tp->t_pgrp = p->p_pgrp;
861		p->p_session->s_ttyp = tp;
862		p->p_flag |= P_CONTROLT;
863		break;
864	case TIOCSPGRP: {		/* set pgrp of tty */
865		register struct pgrp *pgrp = pgfind(*(int *)data);
866
867		if (!isctty(p, tp))
868			return (ENOTTY);
869		else if (pgrp == NULL || pgrp->pg_session != p->p_session)
870			return (EPERM);
871		tp->t_pgrp = pgrp;
872		break;
873	}
874	case TIOCSWINSZ:		/* set window size */
875		if (bcmp((caddr_t)&tp->t_winsize, data,
876		    sizeof (struct winsize))) {
877			tp->t_winsize = *(struct winsize *)data;
878			pgsignal(tp->t_pgrp, SIGWINCH, 1);
879		}
880		break;
881	default:
882#if defined(COMPAT_43) || defined(COMPAT_SUNOS)
883		return (ttcompat(tp, cmd, data, flag));
884#else
885		return (-1);
886#endif
887	}
888	return (0);
889}
890
891int
892ttselect(device, rw, p)
893	dev_t device;
894	int rw;
895	struct proc *p;
896{
897	register struct tty *tp;
898	int nread, s;
899
900	tp = &cdevsw[major(device)].d_ttys[minor(device)];
901
902	s = spltty();
903	switch (rw) {
904	case FREAD:
905		nread = ttnread(tp);
906		if (nread > 0 || !ISSET(tp->t_cflag, CLOCAL) &&
907		    !ISSET(tp->t_state, TS_CARR_ON))
908			goto win;
909		selrecord(p, &tp->t_rsel);
910		break;
911	case FWRITE:
912		if (tp->t_outq.c_cc <= tp->t_lowat) {
913win:			splx(s);
914			return (1);
915		}
916		selrecord(p, &tp->t_wsel);
917		break;
918	}
919	splx(s);
920	return (0);
921}
922
923static int
924ttnread(tp)
925	struct tty *tp;
926{
927	int nread;
928
929	if (ISSET(tp->t_lflag, PENDIN))
930		ttypend(tp);
931	nread = tp->t_canq.c_cc;
932	if (!ISSET(tp->t_lflag, ICANON))
933		nread += tp->t_rawq.c_cc;
934	return (nread);
935}
936
937/*
938 * Wait for output to drain.
939 */
940int
941ttywait(tp)
942	register struct tty *tp;
943{
944	int error, s;
945
946	error = 0;
947	s = spltty();
948	while ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
949	    (ISSET(tp->t_state, TS_CARR_ON) || ISSET(tp->t_cflag, CLOCAL))
950	    && tp->t_oproc) {
951		(*tp->t_oproc)(tp);
952		SET(tp->t_state, TS_ASLEEP);
953		if (error = ttysleep(tp,
954		    &tp->t_outq, TTOPRI | PCATCH, ttyout, 0))
955			break;
956	}
957	splx(s);
958	return (error);
959}
960
961/*
962 * Flush if successfully wait.
963 */
964int
965ttywflush(tp)
966	struct tty *tp;
967{
968	int error;
969
970	if ((error = ttywait(tp)) == 0)
971		ttyflush(tp, FREAD);
972	return (error);
973}
974
975/*
976 * Flush tty read and/or write queues, notifying anyone waiting.
977 */
978void
979ttyflush(tp, rw)
980	register struct tty *tp;
981	int rw;
982{
983	register int s;
984
985	s = spltty();
986	if (rw & FREAD) {
987		FLUSHQ(&tp->t_canq);
988		FLUSHQ(&tp->t_rawq);
989		tp->t_rocount = 0;
990		tp->t_rocol = 0;
991		CLR(tp->t_state, TS_LOCAL);
992		ttwakeup(tp);
993	}
994	if (rw & FWRITE) {
995		CLR(tp->t_state, TS_TTSTOP);
996#ifdef sun4c						/* XXX */
997		(*tp->t_stop)(tp, rw);
998#else
999		(*cdevsw[major(tp->t_dev)].d_stop)(tp, rw);
1000#endif
1001		FLUSHQ(&tp->t_outq);
1002		wakeup((caddr_t)&tp->t_outq);
1003		selwakeup(&tp->t_wsel);
1004	}
1005	splx(s);
1006}
1007
1008/*
1009 * Copy in the default termios characters.
1010 */
1011void
1012ttychars(tp)
1013	struct tty *tp;
1014{
1015
1016	bcopy(ttydefchars, tp->t_cc, sizeof(ttydefchars));
1017}
1018
1019/*
1020 * Send stop character on input overflow.
1021 */
1022static void
1023ttyblock(tp)
1024	register struct tty *tp;
1025{
1026	register int total;
1027
1028	total = tp->t_rawq.c_cc + tp->t_canq.c_cc;
1029	if (tp->t_rawq.c_cc > TTYHOG) {
1030		ttyflush(tp, FREAD | FWRITE);
1031		CLR(tp->t_state, TS_TBLOCK);
1032	}
1033	/*
1034	 * Block further input iff: current input > threshold
1035	 * AND input is available to user program.
1036	 */
1037	if (total >= TTYHOG / 2 &&
1038	    !ISSET(tp->t_state, TS_TBLOCK) &&
1039	    !ISSET(tp->t_lflag, ICANON) || tp->t_canq.c_cc > 0 &&
1040	    tp->t_cc[VSTOP] != _POSIX_VDISABLE) {
1041		if (putc(tp->t_cc[VSTOP], &tp->t_outq) == 0) {
1042			SET(tp->t_state, TS_TBLOCK);
1043			ttstart(tp);
1044		}
1045	}
1046}
1047
1048void
1049ttrstrt(tp_arg)
1050	void *tp_arg;
1051{
1052	struct tty *tp;
1053	int s;
1054
1055#ifdef DIAGNOSTIC
1056	if (tp_arg == NULL)
1057		panic("ttrstrt");
1058#endif
1059	tp = tp_arg;
1060	s = spltty();
1061
1062	CLR(tp->t_state, TS_TIMEOUT);
1063	ttstart(tp);
1064
1065	splx(s);
1066}
1067
1068int
1069ttstart(tp)
1070	struct tty *tp;
1071{
1072
1073	if (tp->t_oproc != NULL)	/* XXX: Kludge for pty. */
1074		(*tp->t_oproc)(tp);
1075	return (0);
1076}
1077
1078/*
1079 * "close" a line discipline
1080 */
1081int
1082ttylclose(tp, flag)
1083	struct tty *tp;
1084	int flag;
1085{
1086
1087	if (flag & IO_NDELAY)
1088		ttyflush(tp, FREAD | FWRITE);
1089	else
1090		ttywflush(tp);
1091	return (0);
1092}
1093
1094/*
1095 * Handle modem control transition on a tty.
1096 * Flag indicates new state of carrier.
1097 * Returns 0 if the line should be turned off, otherwise 1.
1098 */
1099int
1100ttymodem(tp, flag)
1101	register struct tty *tp;
1102	int flag;
1103{
1104
1105	if (!ISSET(tp->t_state, TS_WOPEN) && ISSET(tp->t_cflag, MDMBUF)) {
1106		/*
1107		 * MDMBUF: do flow control according to carrier flag
1108		 */
1109		if (flag) {
1110			CLR(tp->t_state, TS_TTSTOP);
1111			ttstart(tp);
1112		} else if (!ISSET(tp->t_state, TS_TTSTOP)) {
1113			SET(tp->t_state, TS_TTSTOP);
1114#ifdef sun4c						/* XXX */
1115			(*tp->t_stop)(tp, 0);
1116#else
1117			(*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
1118#endif
1119		}
1120	} else if (flag == 0) {
1121		/*
1122		 * Lost carrier.
1123		 */
1124		CLR(tp->t_state, TS_CARR_ON);
1125		if (ISSET(tp->t_state, TS_ISOPEN) &&
1126		    !ISSET(tp->t_cflag, CLOCAL)) {
1127			if (tp->t_session && tp->t_session->s_leader)
1128				psignal(tp->t_session->s_leader, SIGHUP);
1129			ttyflush(tp, FREAD | FWRITE);
1130			return (0);
1131		}
1132	} else {
1133		/*
1134		 * Carrier now on.
1135		 */
1136		SET(tp->t_state, TS_CARR_ON);
1137		ttwakeup(tp);
1138	}
1139	return (1);
1140}
1141
1142/*
1143 * Default modem control routine (for other line disciplines).
1144 * Return argument flag, to turn off device on carrier drop.
1145 */
1146int
1147nullmodem(tp, flag)
1148	register struct tty *tp;
1149	int flag;
1150{
1151
1152	if (flag)
1153		SET(tp->t_state, TS_CARR_ON);
1154	else {
1155		CLR(tp->t_state, TS_CARR_ON);
1156		if (!ISSET(tp->t_cflag, CLOCAL)) {
1157			if (tp->t_session && tp->t_session->s_leader)
1158				psignal(tp->t_session->s_leader, SIGHUP);
1159			return (0);
1160		}
1161	}
1162	return (1);
1163}
1164
1165/*
1166 * Reinput pending characters after state switch
1167 * call at spltty().
1168 */
1169void
1170ttypend(tp)
1171	register struct tty *tp;
1172{
1173	struct clist tq;
1174	register c;
1175
1176	CLR(tp->t_lflag, PENDIN);
1177	SET(tp->t_state, TS_TYPEN);
1178	tq = tp->t_rawq;
1179	tp->t_rawq.c_cc = 0;
1180	tp->t_rawq.c_cf = tp->t_rawq.c_cl = 0;
1181	while ((c = getc(&tq)) >= 0)
1182		ttyinput(c, tp);
1183	CLR(tp->t_state, TS_TYPEN);
1184}
1185
1186/*
1187 * Process a read call on a tty device.
1188 */
1189int
1190ttread(tp, uio, flag)
1191	register struct tty *tp;
1192	struct uio *uio;
1193	int flag;
1194{
1195	register struct clist *qp;
1196	register int c;
1197	register long lflag;
1198	register u_char *cc = tp->t_cc;
1199	register struct proc *p = curproc;
1200	int s, first, error = 0;
1201
1202loop:	lflag = tp->t_lflag;
1203	s = spltty();
1204	/*
1205	 * take pending input first
1206	 */
1207	if (ISSET(lflag, PENDIN))
1208		ttypend(tp);
1209	splx(s);
1210
1211	/*
1212	 * Hang process if it's in the background.
1213	 */
1214	if (isbackground(p, tp)) {
1215		if ((p->p_sigignore & sigmask(SIGTTIN)) ||
1216		   (p->p_sigmask & sigmask(SIGTTIN)) ||
1217		    p->p_flag & P_PPWAIT || p->p_pgrp->pg_jobc == 0)
1218			return (EIO);
1219		pgsignal(p->p_pgrp, SIGTTIN, 1);
1220		if (error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, ttybg, 0))
1221			return (error);
1222		goto loop;
1223	}
1224
1225	/*
1226	 * If canonical, use the canonical queue,
1227	 * else use the raw queue.
1228	 *
1229	 * (should get rid of clists...)
1230	 */
1231	qp = ISSET(lflag, ICANON) ? &tp->t_canq : &tp->t_rawq;
1232
1233	/*
1234	 * If there is no input, sleep on rawq
1235	 * awaiting hardware receipt and notification.
1236	 * If we have data, we don't need to check for carrier.
1237	 */
1238	s = spltty();
1239	if (qp->c_cc <= 0) {
1240		int carrier;
1241
1242		carrier = ISSET(tp->t_state, TS_CARR_ON) ||
1243		    ISSET(tp->t_cflag, CLOCAL);
1244		if (!carrier && ISSET(tp->t_state, TS_ISOPEN)) {
1245			splx(s);
1246			return (0);	/* EOF */
1247		}
1248		if (flag & IO_NDELAY) {
1249			splx(s);
1250			return (EWOULDBLOCK);
1251		}
1252		error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH,
1253		    carrier ? ttyin : ttopen, 0);
1254		splx(s);
1255		if (error)
1256			return (error);
1257		goto loop;
1258	}
1259	splx(s);
1260
1261	/*
1262	 * Input present, check for input mapping and processing.
1263	 */
1264	first = 1;
1265	while ((c = getc(qp)) >= 0) {
1266		/*
1267		 * delayed suspend (^Y)
1268		 */
1269		if (CCEQ(cc[VDSUSP], c) && ISSET(lflag, ISIG)) {
1270			pgsignal(tp->t_pgrp, SIGTSTP, 1);
1271			if (first) {
1272				if (error = ttysleep(tp,
1273				    &lbolt, TTIPRI | PCATCH, ttybg, 0))
1274					break;
1275				goto loop;
1276			}
1277			break;
1278		}
1279		/*
1280		 * Interpret EOF only in canonical mode.
1281		 */
1282		if (CCEQ(cc[VEOF], c) && ISSET(lflag, ICANON))
1283			break;
1284		/*
1285		 * Give user character.
1286		 */
1287 		error = ureadc(c, uio);
1288		if (error)
1289			break;
1290 		if (uio->uio_resid == 0)
1291			break;
1292		/*
1293		 * In canonical mode check for a "break character"
1294		 * marking the end of a "line of input".
1295		 */
1296		if (ISSET(lflag, ICANON) && TTBREAKC(c))
1297			break;
1298		first = 0;
1299	}
1300	/*
1301	 * Look to unblock output now that (presumably)
1302	 * the input queue has gone down.
1303	 */
1304	s = spltty();
1305	if (ISSET(tp->t_state, TS_TBLOCK) && tp->t_rawq.c_cc < TTYHOG/5) {
1306		if (cc[VSTART] != _POSIX_VDISABLE &&
1307		    putc(cc[VSTART], &tp->t_outq) == 0) {
1308			CLR(tp->t_state, TS_TBLOCK);
1309			ttstart(tp);
1310		}
1311	}
1312	splx(s);
1313	return (error);
1314}
1315
1316/*
1317 * Check the output queue on tp for space for a kernel message (from uprintf
1318 * or tprintf).  Allow some space over the normal hiwater mark so we don't
1319 * lose messages due to normal flow control, but don't let the tty run amok.
1320 * Sleeps here are not interruptible, but we return prematurely if new signals
1321 * arrive.
1322 */
1323int
1324ttycheckoutq(tp, wait)
1325	register struct tty *tp;
1326	int wait;
1327{
1328	int hiwat, s, oldsig;
1329
1330	hiwat = tp->t_hiwat;
1331	s = spltty();
1332	oldsig = wait ? curproc->p_siglist : 0;
1333	if (tp->t_outq.c_cc > hiwat + 200)
1334		while (tp->t_outq.c_cc > hiwat) {
1335			ttstart(tp);
1336			if (wait == 0 || curproc->p_siglist != oldsig) {
1337				splx(s);
1338				return (0);
1339			}
1340			timeout((void (*)__P((void *)))wakeup,
1341			    (void *)&tp->t_outq, hz);
1342			SET(tp->t_state, TS_ASLEEP);
1343			sleep((caddr_t)&tp->t_outq, PZERO - 1);
1344		}
1345	splx(s);
1346	return (1);
1347}
1348
1349/*
1350 * Process a write call on a tty device.
1351 */
1352int
1353ttwrite(tp, uio, flag)
1354	register struct tty *tp;
1355	register struct uio *uio;
1356	int flag;
1357{
1358	register char *cp = 0;
1359	register int cc, ce;
1360	register struct proc *p;
1361	int i, hiwat, cnt, error, s;
1362	char obuf[OBUFSIZ];
1363
1364	hiwat = tp->t_hiwat;
1365	cnt = uio->uio_resid;
1366	error = 0;
1367	cc = 0;
1368loop:
1369	s = spltty();
1370	if (!ISSET(tp->t_state, TS_CARR_ON) &&
1371	    !ISSET(tp->t_cflag, CLOCAL)) {
1372		if (ISSET(tp->t_state, TS_ISOPEN)) {
1373			splx(s);
1374			return (EIO);
1375		} else if (flag & IO_NDELAY) {
1376			splx(s);
1377			error = EWOULDBLOCK;
1378			goto out;
1379		} else {
1380			/* Sleep awaiting carrier. */
1381			error = ttysleep(tp,
1382			    &tp->t_rawq, TTIPRI | PCATCH,ttopen, 0);
1383			splx(s);
1384			if (error)
1385				goto out;
1386			goto loop;
1387		}
1388	}
1389	splx(s);
1390	/*
1391	 * Hang the process if it's in the background.
1392	 */
1393	p = curproc;
1394	if (isbackground(p, tp) &&
1395	    ISSET(tp->t_lflag, TOSTOP) && (p->p_flag & P_PPWAIT) == 0 &&
1396	    (p->p_sigignore & sigmask(SIGTTOU)) == 0 &&
1397	    (p->p_sigmask & sigmask(SIGTTOU)) == 0 &&
1398	     p->p_pgrp->pg_jobc) {
1399		pgsignal(p->p_pgrp, SIGTTOU, 1);
1400		if (error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, ttybg, 0))
1401			goto out;
1402		goto loop;
1403	}
1404	/*
1405	 * Process the user's data in at most OBUFSIZ chunks.  Perform any
1406	 * output translation.  Keep track of high water mark, sleep on
1407	 * overflow awaiting device aid in acquiring new space.
1408	 */
1409	while (uio->uio_resid > 0 || cc > 0) {
1410		if (ISSET(tp->t_lflag, FLUSHO)) {
1411			uio->uio_resid = 0;
1412			return (0);
1413		}
1414		if (tp->t_outq.c_cc > hiwat)
1415			goto ovhiwat;
1416		/*
1417		 * Grab a hunk of data from the user, unless we have some
1418		 * leftover from last time.
1419		 */
1420		if (cc == 0) {
1421			cc = min(uio->uio_resid, OBUFSIZ);
1422			cp = obuf;
1423			error = uiomove(cp, cc, uio);
1424			if (error) {
1425				cc = 0;
1426				break;
1427			}
1428		}
1429		/*
1430		 * If nothing fancy need be done, grab those characters we
1431		 * can handle without any of ttyoutput's processing and
1432		 * just transfer them to the output q.  For those chars
1433		 * which require special processing (as indicated by the
1434		 * bits in char_type), call ttyoutput.  After processing
1435		 * a hunk of data, look for FLUSHO so ^O's will take effect
1436		 * immediately.
1437		 */
1438		while (cc > 0) {
1439			if (!ISSET(tp->t_oflag, OPOST))
1440				ce = cc;
1441			else {
1442				ce = cc - scanc((u_int)cc, (u_char *)cp,
1443				   (u_char *)char_type, CCLASSMASK);
1444				/*
1445				 * If ce is zero, then we're processing
1446				 * a special character through ttyoutput.
1447				 */
1448				if (ce == 0) {
1449					tp->t_rocount = 0;
1450					if (ttyoutput(*cp, tp) >= 0) {
1451						/* No Clists, wait a bit. */
1452						ttstart(tp);
1453						if (error = ttysleep(tp, &lbolt,
1454						    TTOPRI | PCATCH, ttybuf, 0))
1455							break;
1456						goto loop;
1457					}
1458					cp++;
1459					cc--;
1460					if (ISSET(tp->t_lflag, FLUSHO) ||
1461					    tp->t_outq.c_cc > hiwat)
1462						goto ovhiwat;
1463					continue;
1464				}
1465			}
1466			/*
1467			 * A bunch of normal characters have been found.
1468			 * Transfer them en masse to the output queue and
1469			 * continue processing at the top of the loop.
1470			 * If there are any further characters in this
1471			 * <= OBUFSIZ chunk, the first should be a character
1472			 * requiring special handling by ttyoutput.
1473			 */
1474			tp->t_rocount = 0;
1475			i = b_to_q(cp, ce, &tp->t_outq);
1476			ce -= i;
1477			tp->t_column += ce;
1478			cp += ce, cc -= ce, tk_nout += ce;
1479			tp->t_outcc += ce;
1480			if (i > 0) {
1481				/* No Clists, wait a bit. */
1482				ttstart(tp);
1483				if (error = ttysleep(tp,
1484				    &lbolt, TTOPRI | PCATCH, ttybuf, 0))
1485					break;
1486				goto loop;
1487			}
1488			if (ISSET(tp->t_lflag, FLUSHO) ||
1489			    tp->t_outq.c_cc > hiwat)
1490				break;
1491		}
1492		ttstart(tp);
1493	}
1494out:
1495	/*
1496	 * If cc is nonzero, we leave the uio structure inconsistent, as the
1497	 * offset and iov pointers have moved forward, but it doesn't matter
1498	 * (the call will either return short or restart with a new uio).
1499	 */
1500	uio->uio_resid += cc;
1501	return (error);
1502
1503ovhiwat:
1504	ttstart(tp);
1505	s = spltty();
1506	/*
1507	 * This can only occur if FLUSHO is set in t_lflag,
1508	 * or if ttstart/oproc is synchronous (or very fast).
1509	 */
1510	if (tp->t_outq.c_cc <= hiwat) {
1511		splx(s);
1512		goto loop;
1513	}
1514	if (flag & IO_NDELAY) {
1515		splx(s);
1516		uio->uio_resid += cc;
1517		return (uio->uio_resid == cnt ? EWOULDBLOCK : 0);
1518	}
1519	SET(tp->t_state, TS_ASLEEP);
1520	error = ttysleep(tp, &tp->t_outq, TTOPRI | PCATCH, ttyout, 0);
1521	splx(s);
1522	if (error)
1523		goto out;
1524	goto loop;
1525}
1526
1527/*
1528 * Rubout one character from the rawq of tp
1529 * as cleanly as possible.
1530 */
1531void
1532ttyrub(c, tp)
1533	register int c;
1534	register struct tty *tp;
1535{
1536	register char *cp;
1537	register int savecol;
1538	int tabc, s;
1539
1540	if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC))
1541		return;
1542	CLR(tp->t_lflag, FLUSHO);
1543	if (ISSET(tp->t_lflag, ECHOE)) {
1544		if (tp->t_rocount == 0) {
1545			/*
1546			 * Screwed by ttwrite; retype
1547			 */
1548			ttyretype(tp);
1549			return;
1550		}
1551		if (c == ('\t' | TTY_QUOTE) || c == ('\n' | TTY_QUOTE))
1552			ttyrubo(tp, 2);
1553		else {
1554			CLR(c, ~TTY_CHARMASK);
1555			switch (CCLASS(c)) {
1556			case ORDINARY:
1557				ttyrubo(tp, 1);
1558				break;
1559			case BACKSPACE:
1560			case CONTROL:
1561			case NEWLINE:
1562			case RETURN:
1563			case VTAB:
1564				if (ISSET(tp->t_lflag, ECHOCTL))
1565					ttyrubo(tp, 2);
1566				break;
1567			case TAB:
1568				if (tp->t_rocount < tp->t_rawq.c_cc) {
1569					ttyretype(tp);
1570					return;
1571				}
1572				s = spltty();
1573				savecol = tp->t_column;
1574				SET(tp->t_state, TS_CNTTB);
1575				SET(tp->t_lflag, FLUSHO);
1576				tp->t_column = tp->t_rocol;
1577				cp = tp->t_rawq.c_cf;
1578				if (cp)
1579					tabc = *cp;	/* XXX FIX NEXTC */
1580				for (; cp; cp = nextc(&tp->t_rawq, cp, &tabc))
1581					ttyecho(tabc, tp);
1582				CLR(tp->t_lflag, FLUSHO);
1583				CLR(tp->t_state, TS_CNTTB);
1584				splx(s);
1585
1586				/* savecol will now be length of the tab. */
1587				savecol -= tp->t_column;
1588				tp->t_column += savecol;
1589				if (savecol > 8)
1590					savecol = 8;	/* overflow screw */
1591				while (--savecol >= 0)
1592					(void)ttyoutput('\b', tp);
1593				break;
1594			default:			/* XXX */
1595#define	PANICSTR	"ttyrub: would panic c = %d, val = %d\n"
1596				(void)printf(PANICSTR, c, CCLASS(c));
1597#ifdef notdef
1598				panic(PANICSTR, c, CCLASS(c));
1599#endif
1600			}
1601		}
1602	} else if (ISSET(tp->t_lflag, ECHOPRT)) {
1603		if (!ISSET(tp->t_state, TS_ERASE)) {
1604			SET(tp->t_state, TS_ERASE);
1605			(void)ttyoutput('\\', tp);
1606		}
1607		ttyecho(c, tp);
1608	} else
1609		ttyecho(tp->t_cc[VERASE], tp);
1610	--tp->t_rocount;
1611}
1612
1613/*
1614 * Back over cnt characters, erasing them.
1615 */
1616static void
1617ttyrubo(tp, cnt)
1618	register struct tty *tp;
1619	int cnt;
1620{
1621
1622	while (cnt-- > 0) {
1623		(void)ttyoutput('\b', tp);
1624		(void)ttyoutput(' ', tp);
1625		(void)ttyoutput('\b', tp);
1626	}
1627}
1628
1629/*
1630 * ttyretype --
1631 *	Reprint the rawq line.  Note, it is assumed that c_cc has already
1632 *	been checked.
1633 */
1634void
1635ttyretype(tp)
1636	register struct tty *tp;
1637{
1638	register char *cp;
1639	int s, c;
1640
1641	/* Echo the reprint character. */
1642	if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE)
1643		ttyecho(tp->t_cc[VREPRINT], tp);
1644
1645	(void)ttyoutput('\n', tp);
1646
1647	/*
1648	 * XXX
1649	 * FIX: NEXTC IS BROKEN - DOESN'T CHECK QUOTE
1650	 * BIT OF FIRST CHAR.
1651	 */
1652	s = spltty();
1653	for (cp = tp->t_canq.c_cf, c = (cp != NULL ? *cp : 0);
1654	    cp != NULL; cp = nextc(&tp->t_canq, cp, &c))
1655		ttyecho(c, tp);
1656	for (cp = tp->t_rawq.c_cf, c = (cp != NULL ? *cp : 0);
1657	    cp != NULL; cp = nextc(&tp->t_rawq, cp, &c))
1658		ttyecho(c, tp);
1659	CLR(tp->t_state, TS_ERASE);
1660	splx(s);
1661
1662	tp->t_rocount = tp->t_rawq.c_cc;
1663	tp->t_rocol = 0;
1664}
1665
1666/*
1667 * Echo a typed character to the terminal.
1668 */
1669static void
1670ttyecho(c, tp)
1671	register int c;
1672	register struct tty *tp;
1673{
1674
1675	if (!ISSET(tp->t_state, TS_CNTTB))
1676		CLR(tp->t_lflag, FLUSHO);
1677	if ((!ISSET(tp->t_lflag, ECHO) &&
1678	    (!ISSET(tp->t_lflag, ECHONL) || c == '\n')) ||
1679	    ISSET(tp->t_lflag, EXTPROC))
1680		return;
1681	if (ISSET(tp->t_lflag, ECHOCTL) &&
1682	    (ISSET(c, TTY_CHARMASK) <= 037 && c != '\t' && c != '\n' ||
1683	    ISSET(c, TTY_CHARMASK) == 0177)) {
1684		(void)ttyoutput('^', tp);
1685		CLR(c, ~TTY_CHARMASK);
1686		if (c == 0177)
1687			c = '?';
1688		else
1689			c += 'A' - 1;
1690	}
1691	(void)ttyoutput(c, tp);
1692}
1693
1694/*
1695 * Wake up any readers on a tty.
1696 */
1697void
1698ttwakeup(tp)
1699	register struct tty *tp;
1700{
1701
1702	selwakeup(&tp->t_rsel);
1703	if (ISSET(tp->t_state, TS_ASYNC))
1704		pgsignal(tp->t_pgrp, SIGIO, 1);
1705	wakeup((caddr_t)&tp->t_rawq);
1706}
1707
1708/*
1709 * Look up a code for a specified speed in a conversion table;
1710 * used by drivers to map software speed values to hardware parameters.
1711 */
1712int
1713ttspeedtab(speed, table)
1714	int speed;
1715	register struct speedtab *table;
1716{
1717
1718	for ( ; table->sp_speed != -1; table++)
1719		if (table->sp_speed == speed)
1720			return (table->sp_code);
1721	return (-1);
1722}
1723
1724/*
1725 * Set tty hi and low water marks.
1726 *
1727 * Try to arrange the dynamics so there's about one second
1728 * from hi to low water.
1729 *
1730 */
1731void
1732ttsetwater(tp)
1733	struct tty *tp;
1734{
1735	register int cps, x;
1736
1737#define CLAMP(x, h, l)	((x) > h ? h : ((x) < l) ? l : (x))
1738
1739	cps = tp->t_ospeed / 10;
1740	tp->t_lowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT);
1741	x += cps;
1742	x = CLAMP(x, TTMAXHIWAT, TTMINHIWAT);
1743	tp->t_hiwat = roundup(x, CBSIZE);
1744#undef	CLAMP
1745}
1746
1747/*
1748 * Report on state of foreground process group.
1749 */
1750void
1751ttyinfo(tp)
1752	register struct tty *tp;
1753{
1754	register struct proc *p, *pick;
1755	struct timeval utime, stime;
1756	int tmp;
1757
1758	if (ttycheckoutq(tp,0) == 0)
1759		return;
1760
1761	/* Print load average. */
1762	tmp = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT;
1763	ttyprintf(tp, "load: %d.%02d ", tmp / 100, tmp % 100);
1764
1765	if (tp->t_session == NULL)
1766		ttyprintf(tp, "not a controlling terminal\n");
1767	else if (tp->t_pgrp == NULL)
1768		ttyprintf(tp, "no foreground process group\n");
1769	else if ((p = tp->t_pgrp->pg_mem) == NULL)
1770		ttyprintf(tp, "empty foreground process group\n");
1771	else {
1772		/* Pick interesting process. */
1773		for (pick = NULL; p != NULL; p = p->p_pgrpnxt)
1774			if (proc_compare(pick, p))
1775				pick = p;
1776
1777		ttyprintf(tp, " cmd: %s %d [%s] ", pick->p_comm, pick->p_pid,
1778		    pick->p_stat == SRUN ? "running" :
1779		    pick->p_wmesg ? pick->p_wmesg : "iowait");
1780
1781		calcru(pick, &utime, &stime, NULL);
1782
1783		/* Print user time. */
1784		ttyprintf(tp, "%d.%02du ",
1785		    utime.tv_sec, (utime.tv_usec + 5000) / 10000);
1786
1787		/* Print system time. */
1788		ttyprintf(tp, "%d.%02ds ",
1789		    stime.tv_sec, (stime.tv_usec + 5000) / 10000);
1790
1791#define	pgtok(a)	(((a) * NBPG) / 1024)
1792		/* Print percentage cpu, resident set size. */
1793		tmp = pick->p_pctcpu * 10000 + FSCALE / 2 >> FSHIFT;
1794		ttyprintf(tp, "%d%% %dk\n",
1795		    tmp / 100,
1796		    pick->p_stat == SIDL || pick->p_stat == SZOMB ? 0 :
1797#ifdef pmap_resident_count
1798			pgtok(pmap_resident_count(&pick->p_vmspace->vm_pmap))
1799#else
1800			pgtok(pick->p_vmspace->vm_rssize)
1801#endif
1802			);
1803	}
1804	tp->t_rocount = 0;	/* so pending input will be retyped if BS */
1805}
1806
1807/*
1808 * Returns 1 if p2 is "better" than p1
1809 *
1810 * The algorithm for picking the "interesting" process is thus:
1811 *
1812 *	1) Only foreground processes are eligible - implied.
1813 *	2) Runnable processes are favored over anything else.  The runner
1814 *	   with the highest cpu utilization is picked (p_estcpu).  Ties are
1815 *	   broken by picking the highest pid.
1816 *	3) The sleeper with the shortest sleep time is next.  With ties,
1817 *	   we pick out just "short-term" sleepers (P_SINTR == 0).
1818 *	4) Further ties are broken by picking the highest pid.
1819 */
1820#define ISRUN(p)	(((p)->p_stat == SRUN) || ((p)->p_stat == SIDL))
1821#define TESTAB(a, b)    ((a)<<1 | (b))
1822#define ONLYA   2
1823#define ONLYB   1
1824#define BOTH    3
1825
1826static int
1827proc_compare(p1, p2)
1828	register struct proc *p1, *p2;
1829{
1830
1831	if (p1 == NULL)
1832		return (1);
1833	/*
1834	 * see if at least one of them is runnable
1835	 */
1836	switch (TESTAB(ISRUN(p1), ISRUN(p2))) {
1837	case ONLYA:
1838		return (0);
1839	case ONLYB:
1840		return (1);
1841	case BOTH:
1842		/*
1843		 * tie - favor one with highest recent cpu utilization
1844		 */
1845		if (p2->p_estcpu > p1->p_estcpu)
1846			return (1);
1847		if (p1->p_estcpu > p2->p_estcpu)
1848			return (0);
1849		return (p2->p_pid > p1->p_pid);	/* tie - return highest pid */
1850	}
1851	/*
1852 	 * weed out zombies
1853	 */
1854	switch (TESTAB(p1->p_stat == SZOMB, p2->p_stat == SZOMB)) {
1855	case ONLYA:
1856		return (1);
1857	case ONLYB:
1858		return (0);
1859	case BOTH:
1860		return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
1861	}
1862	/*
1863	 * pick the one with the smallest sleep time
1864	 */
1865	if (p2->p_slptime > p1->p_slptime)
1866		return (0);
1867	if (p1->p_slptime > p2->p_slptime)
1868		return (1);
1869	/*
1870	 * favor one sleeping in a non-interruptible sleep
1871	 */
1872	if (p1->p_flag & P_SINTR && (p2->p_flag & P_SINTR) == 0)
1873		return (1);
1874	if (p2->p_flag & P_SINTR && (p1->p_flag & P_SINTR) == 0)
1875		return (0);
1876	return (p2->p_pid > p1->p_pid);		/* tie - return highest pid */
1877}
1878
1879/*
1880 * Output char to tty; console putchar style.
1881 */
1882int
1883tputchar(c, tp)
1884	int c;
1885	struct tty *tp;
1886{
1887	register int s;
1888
1889	s = spltty();
1890	if (ISSET(tp->t_state,
1891	    TS_CARR_ON | TS_ISOPEN) != (TS_CARR_ON | TS_ISOPEN)) {
1892		splx(s);
1893		return (-1);
1894	}
1895	if (c == '\n')
1896		(void)ttyoutput('\r', tp);
1897	(void)ttyoutput(c, tp);
1898	ttstart(tp);
1899	splx(s);
1900	return (0);
1901}
1902
1903/*
1904 * Sleep on chan, returning ERESTART if tty changed while we napped and
1905 * returning any errors (e.g. EINTR/ETIMEDOUT) reported by tsleep.  If
1906 * the tty is revoked, restarting a pending call will redo validation done
1907 * at the start of the call.
1908 */
1909int
1910ttysleep(tp, chan, pri, wmesg, timo)
1911	struct tty *tp;
1912	void *chan;
1913	int pri, timo;
1914	char *wmesg;
1915{
1916	int error;
1917	short gen;
1918
1919	gen = tp->t_gen;
1920	if (error = tsleep(chan, pri, wmesg, timo))
1921		return (error);
1922	return (tp->t_gen == gen ? 0 : ERESTART);
1923}
1924