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