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