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