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