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