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