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