tty.c revision 1.82 1 /* $NetBSD: tty.c,v 1.82 1997/04/04 15:10:34 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 /* VMIN == 0: any quantity read satisfies */
1357 if (cc[VMIN] == 0 && error == EWOULDBLOCK)
1358 return (0);
1359 if (error && error != EWOULDBLOCK)
1360 return (error);
1361 goto loop;
1362 }
1363 read:
1364 splx(s);
1365
1366 /*
1367 * Input present, check for input mapping and processing.
1368 */
1369 first = 1;
1370 while ((c = getc(qp)) >= 0) {
1371 /*
1372 * delayed suspend (^Y)
1373 */
1374 if (CCEQ(cc[VDSUSP], c) &&
1375 ISSET(lflag, IEXTEN|ISIG) == (IEXTEN|ISIG)) {
1376 pgsignal(tp->t_pgrp, SIGTSTP, 1);
1377 if (first) {
1378 error = ttysleep(tp, &lbolt,
1379 TTIPRI | PCATCH, ttybg, 0);
1380 if (error)
1381 break;
1382 goto loop;
1383 }
1384 break;
1385 }
1386 /*
1387 * Interpret EOF only in canonical mode.
1388 */
1389 if (CCEQ(cc[VEOF], c) && ISSET(lflag, ICANON))
1390 break;
1391 /*
1392 * Give user character.
1393 */
1394 error = ureadc(c, uio);
1395 if (error)
1396 break;
1397 if (uio->uio_resid == 0)
1398 break;
1399 /*
1400 * In canonical mode check for a "break character"
1401 * marking the end of a "line of input".
1402 */
1403 if (ISSET(lflag, ICANON) && TTBREAKC(c))
1404 break;
1405 first = 0;
1406 }
1407 /*
1408 * Look to unblock output now that (presumably)
1409 * the input queue has gone down.
1410 */
1411 s = spltty();
1412 if (ISSET(tp->t_state, TS_TBLOCK) && tp->t_rawq.c_cc < TTYHOG/5) {
1413 if (ISSET(tp->t_iflag, IXOFF) &&
1414 cc[VSTART] != _POSIX_VDISABLE &&
1415 putc(cc[VSTART], &tp->t_outq) == 0) {
1416 CLR(tp->t_state, TS_TBLOCK);
1417 ttstart(tp);
1418 }
1419 /* Try to unblock remote output via hardware flow control. */
1420 if (ISSET(tp->t_cflag, CHWFLOW) && tp->t_hwiflow &&
1421 (*tp->t_hwiflow)(tp, 0) != 0)
1422 CLR(tp->t_state, TS_TBLOCK);
1423 }
1424 splx(s);
1425 return (error);
1426 }
1427
1428 /*
1429 * Check the output queue on tp for space for a kernel message (from uprintf
1430 * or tprintf). Allow some space over the normal hiwater mark so we don't
1431 * lose messages due to normal flow control, but don't let the tty run amok.
1432 * Sleeps here are not interruptible, but we return prematurely if new signals
1433 * arrive.
1434 */
1435 int
1436 ttycheckoutq(tp, wait)
1437 register struct tty *tp;
1438 int wait;
1439 {
1440 int hiwat, s, oldsig;
1441
1442 hiwat = tp->t_hiwat;
1443 s = spltty();
1444 oldsig = wait ? curproc->p_siglist : 0;
1445 if (tp->t_outq.c_cc > hiwat + 200)
1446 while (tp->t_outq.c_cc > hiwat) {
1447 ttstart(tp);
1448 if (wait == 0 || curproc->p_siglist != oldsig) {
1449 splx(s);
1450 return (0);
1451 }
1452 timeout((void (*)__P((void *)))wakeup,
1453 (void *)&tp->t_outq, hz);
1454 SET(tp->t_state, TS_ASLEEP);
1455 tsleep(&tp->t_outq, PZERO - 1, "ttckoutq", 0);
1456 }
1457 splx(s);
1458 return (1);
1459 }
1460
1461 /*
1462 * Process a write call on a tty device.
1463 */
1464 int
1465 ttwrite(tp, uio, flag)
1466 register struct tty *tp;
1467 register struct uio *uio;
1468 int flag;
1469 {
1470 register u_char *cp = NULL;
1471 register int cc, ce;
1472 register struct proc *p;
1473 int i, hiwat, cnt, error, s;
1474 u_char obuf[OBUFSIZ];
1475
1476 hiwat = tp->t_hiwat;
1477 cnt = uio->uio_resid;
1478 error = 0;
1479 cc = 0;
1480 loop:
1481 s = spltty();
1482 if (!ISSET(tp->t_state, TS_CARR_ON) &&
1483 !ISSET(tp->t_cflag, CLOCAL)) {
1484 if (ISSET(tp->t_state, TS_ISOPEN)) {
1485 splx(s);
1486 return (EIO);
1487 } else if (flag & IO_NDELAY) {
1488 splx(s);
1489 error = EWOULDBLOCK;
1490 goto out;
1491 } else {
1492 /* Sleep awaiting carrier. */
1493 error = ttysleep(tp,
1494 &tp->t_rawq, TTIPRI | PCATCH, ttopen, 0);
1495 splx(s);
1496 if (error)
1497 goto out;
1498 goto loop;
1499 }
1500 }
1501 splx(s);
1502 /*
1503 * Hang the process if it's in the background.
1504 */
1505 p = curproc;
1506 if (isbackground(p, tp) &&
1507 ISSET(tp->t_lflag, TOSTOP) && (p->p_flag & P_PPWAIT) == 0 &&
1508 (p->p_sigignore & sigmask(SIGTTOU)) == 0 &&
1509 (p->p_sigmask & sigmask(SIGTTOU)) == 0 &&
1510 p->p_pgrp->pg_jobc) {
1511 pgsignal(p->p_pgrp, SIGTTOU, 1);
1512 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, ttybg, 0);
1513 if (error)
1514 goto out;
1515 goto loop;
1516 }
1517 /*
1518 * Process the user's data in at most OBUFSIZ chunks. Perform any
1519 * output translation. Keep track of high water mark, sleep on
1520 * overflow awaiting device aid in acquiring new space.
1521 */
1522 while (uio->uio_resid > 0 || cc > 0) {
1523 if (ISSET(tp->t_lflag, FLUSHO)) {
1524 uio->uio_resid = 0;
1525 return (0);
1526 }
1527 if (tp->t_outq.c_cc > hiwat)
1528 goto ovhiwat;
1529 /*
1530 * Grab a hunk of data from the user, unless we have some
1531 * leftover from last time.
1532 */
1533 if (cc == 0) {
1534 cc = min(uio->uio_resid, OBUFSIZ);
1535 cp = obuf;
1536 error = uiomove(cp, cc, uio);
1537 if (error) {
1538 cc = 0;
1539 break;
1540 }
1541 }
1542 /*
1543 * If nothing fancy need be done, grab those characters we
1544 * can handle without any of ttyoutput's processing and
1545 * just transfer them to the output q. For those chars
1546 * which require special processing (as indicated by the
1547 * bits in char_type), call ttyoutput. After processing
1548 * a hunk of data, look for FLUSHO so ^O's will take effect
1549 * immediately.
1550 */
1551 while (cc > 0) {
1552 if (!ISSET(tp->t_oflag, OPOST))
1553 ce = cc;
1554 else {
1555 ce = cc - scanc((u_int)cc, cp, char_type,
1556 CCLASSMASK);
1557 /*
1558 * If ce is zero, then we're processing
1559 * a special character through ttyoutput.
1560 */
1561 if (ce == 0) {
1562 tp->t_rocount = 0;
1563 if (ttyoutput(*cp, tp) >= 0) {
1564 #ifdef REAL_CLISTS
1565 /* No Clists, wait a bit. */
1566 ttstart(tp);
1567 if (error = ttysleep(tp, &lbolt,
1568 TTOPRI | PCATCH, ttybuf, 0))
1569 break;
1570 goto loop;
1571 #else
1572 /* out of space */
1573 goto overfull;
1574 #endif
1575 }
1576 cp++;
1577 cc--;
1578 if (ISSET(tp->t_lflag, FLUSHO) ||
1579 tp->t_outq.c_cc > hiwat)
1580 goto ovhiwat;
1581 continue;
1582 }
1583 }
1584 /*
1585 * A bunch of normal characters have been found.
1586 * Transfer them en masse to the output queue and
1587 * continue processing at the top of the loop.
1588 * If there are any further characters in this
1589 * <= OBUFSIZ chunk, the first should be a character
1590 * requiring special handling by ttyoutput.
1591 */
1592 tp->t_rocount = 0;
1593 i = b_to_q(cp, ce, &tp->t_outq);
1594 ce -= i;
1595 tp->t_column += ce;
1596 cp += ce, cc -= ce, tk_nout += ce;
1597 tp->t_outcc += ce;
1598 if (i > 0) {
1599 #ifdef REAL_CLISTS
1600 /* No Clists, wait a bit. */
1601 ttstart(tp);
1602 if (error = ttysleep(tp,
1603 &lbolt, TTOPRI | PCATCH, ttybuf, 0))
1604 break;
1605 goto loop;
1606 #else
1607 /* out of space */
1608 goto overfull;
1609 #endif
1610 }
1611 if (ISSET(tp->t_lflag, FLUSHO) ||
1612 tp->t_outq.c_cc > hiwat)
1613 break;
1614 }
1615 ttstart(tp);
1616 }
1617 out:
1618 /*
1619 * If cc is nonzero, we leave the uio structure inconsistent, as the
1620 * offset and iov pointers have moved forward, but it doesn't matter
1621 * (the call will either return short or restart with a new uio).
1622 */
1623 uio->uio_resid += cc;
1624 return (error);
1625
1626 #ifndef REAL_CLISTS
1627 overfull:
1628 /*
1629 * Since we are using ring buffers, if we can't insert any more into
1630 * the output queue, we can assume the ring is full and that someone
1631 * forgot to set the high water mark correctly. We set it and then
1632 * proceed as normal.
1633 */
1634 hiwat = tp->t_outq.c_cc - 1;
1635 #endif
1636
1637 ovhiwat:
1638 ttstart(tp);
1639 s = spltty();
1640 /*
1641 * This can only occur if FLUSHO is set in t_lflag,
1642 * or if ttstart/oproc is synchronous (or very fast).
1643 */
1644 if (tp->t_outq.c_cc <= hiwat) {
1645 splx(s);
1646 goto loop;
1647 }
1648 if (flag & IO_NDELAY) {
1649 splx(s);
1650 uio->uio_resid += cc;
1651 return (uio->uio_resid == cnt ? EWOULDBLOCK : 0);
1652 }
1653 SET(tp->t_state, TS_ASLEEP);
1654 error = ttysleep(tp, &tp->t_outq, TTOPRI | PCATCH, ttyout, 0);
1655 splx(s);
1656 if (error)
1657 goto out;
1658 goto loop;
1659 }
1660
1661 /*
1662 * Rubout one character from the rawq of tp
1663 * as cleanly as possible.
1664 */
1665 void
1666 ttyrub(c, tp)
1667 int c;
1668 register struct tty *tp;
1669 {
1670 register u_char *cp;
1671 register int savecol;
1672 int tabc, s;
1673
1674 if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC))
1675 return;
1676 CLR(tp->t_lflag, FLUSHO);
1677 if (ISSET(tp->t_lflag, ECHOE)) {
1678 if (tp->t_rocount == 0) {
1679 /*
1680 * Screwed by ttwrite; retype
1681 */
1682 ttyretype(tp);
1683 return;
1684 }
1685 if (c == ('\t' | TTY_QUOTE) || c == ('\n' | TTY_QUOTE))
1686 ttyrubo(tp, 2);
1687 else {
1688 CLR(c, ~TTY_CHARMASK);
1689 switch (CCLASS(c)) {
1690 case ORDINARY:
1691 ttyrubo(tp, 1);
1692 break;
1693 case BACKSPACE:
1694 case CONTROL:
1695 case NEWLINE:
1696 case RETURN:
1697 case VTAB:
1698 if (ISSET(tp->t_lflag, ECHOCTL))
1699 ttyrubo(tp, 2);
1700 break;
1701 case TAB:
1702 if (tp->t_rocount < tp->t_rawq.c_cc) {
1703 ttyretype(tp);
1704 return;
1705 }
1706 s = spltty();
1707 savecol = tp->t_column;
1708 SET(tp->t_state, TS_CNTTB);
1709 SET(tp->t_lflag, FLUSHO);
1710 tp->t_column = tp->t_rocol;
1711 for (cp = firstc(&tp->t_rawq, &tabc); cp;
1712 cp = nextc(&tp->t_rawq, cp, &tabc))
1713 ttyecho(tabc, tp);
1714 CLR(tp->t_lflag, FLUSHO);
1715 CLR(tp->t_state, TS_CNTTB);
1716 splx(s);
1717
1718 /* savecol will now be length of the tab. */
1719 savecol -= tp->t_column;
1720 tp->t_column += savecol;
1721 if (savecol > 8)
1722 savecol = 8; /* overflow screw */
1723 while (--savecol >= 0)
1724 (void)ttyoutput('\b', tp);
1725 break;
1726 default: /* XXX */
1727 #define PANICSTR "ttyrub: would panic c = %d, val = %d\n"
1728 (void)printf(PANICSTR, c, CCLASS(c));
1729 #ifdef notdef
1730 panic(PANICSTR, c, CCLASS(c));
1731 #endif
1732 }
1733 }
1734 } else if (ISSET(tp->t_lflag, ECHOPRT)) {
1735 if (!ISSET(tp->t_state, TS_ERASE)) {
1736 SET(tp->t_state, TS_ERASE);
1737 (void)ttyoutput('\\', tp);
1738 }
1739 ttyecho(c, tp);
1740 } else
1741 ttyecho(tp->t_cc[VERASE], tp);
1742 --tp->t_rocount;
1743 }
1744
1745 /*
1746 * Back over cnt characters, erasing them.
1747 */
1748 static void
1749 ttyrubo(tp, cnt)
1750 register struct tty *tp;
1751 int cnt;
1752 {
1753
1754 while (cnt-- > 0) {
1755 (void)ttyoutput('\b', tp);
1756 (void)ttyoutput(' ', tp);
1757 (void)ttyoutput('\b', tp);
1758 }
1759 }
1760
1761 /*
1762 * ttyretype --
1763 * Reprint the rawq line. Note, it is assumed that c_cc has already
1764 * been checked.
1765 */
1766 void
1767 ttyretype(tp)
1768 register struct tty *tp;
1769 {
1770 register u_char *cp;
1771 int s, c;
1772
1773 /* Echo the reprint character. */
1774 if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE)
1775 ttyecho(tp->t_cc[VREPRINT], tp);
1776
1777 (void)ttyoutput('\n', tp);
1778
1779 s = spltty();
1780 for (cp = firstc(&tp->t_canq, &c); cp; cp = nextc(&tp->t_canq, cp, &c))
1781 ttyecho(c, tp);
1782 for (cp = firstc(&tp->t_rawq, &c); cp; cp = nextc(&tp->t_rawq, cp, &c))
1783 ttyecho(c, tp);
1784 CLR(tp->t_state, TS_ERASE);
1785 splx(s);
1786
1787 tp->t_rocount = tp->t_rawq.c_cc;
1788 tp->t_rocol = 0;
1789 }
1790
1791 /*
1792 * Echo a typed character to the terminal.
1793 */
1794 static void
1795 ttyecho(c, tp)
1796 register int c;
1797 register struct tty *tp;
1798 {
1799
1800 if (!ISSET(tp->t_state, TS_CNTTB))
1801 CLR(tp->t_lflag, FLUSHO);
1802 if ((!ISSET(tp->t_lflag, ECHO) &&
1803 (!ISSET(tp->t_lflag, ECHONL) || c != '\n')) ||
1804 ISSET(tp->t_lflag, EXTPROC))
1805 return;
1806 if (((ISSET(tp->t_lflag, ECHOCTL) &&
1807 (ISSET(c, TTY_CHARMASK) <= 037 && c != '\t' && c != '\n')) ||
1808 ISSET(c, TTY_CHARMASK) == 0177)) {
1809 (void)ttyoutput('^', tp);
1810 CLR(c, ~TTY_CHARMASK);
1811 if (c == 0177)
1812 c = '?';
1813 else
1814 c += 'A' - 1;
1815 }
1816 (void)ttyoutput(c, tp);
1817 }
1818
1819 /*
1820 * Wake up any readers on a tty.
1821 */
1822 void
1823 ttwakeup(tp)
1824 register struct tty *tp;
1825 {
1826
1827 selwakeup(&tp->t_rsel);
1828 if (ISSET(tp->t_state, TS_ASYNC))
1829 pgsignal(tp->t_pgrp, SIGIO, 1);
1830 wakeup((caddr_t)&tp->t_rawq);
1831 }
1832
1833 /*
1834 * Look up a code for a specified speed in a conversion table;
1835 * used by drivers to map software speed values to hardware parameters.
1836 */
1837 int
1838 ttspeedtab(speed, table)
1839 int speed;
1840 register struct speedtab *table;
1841 {
1842
1843 for ( ; table->sp_speed != -1; table++)
1844 if (table->sp_speed == speed)
1845 return (table->sp_code);
1846 return (-1);
1847 }
1848
1849 /*
1850 * Set tty hi and low water marks.
1851 *
1852 * Try to arrange the dynamics so there's about one second
1853 * from hi to low water.
1854 */
1855 void
1856 ttsetwater(tp)
1857 struct tty *tp;
1858 {
1859 register int cps, x;
1860
1861 #define CLAMP(x, h, l) ((x) > h ? h : ((x) < l) ? l : (x))
1862
1863 cps = tp->t_ospeed / 10;
1864 tp->t_lowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT);
1865 x += cps;
1866 x = CLAMP(x, TTMAXHIWAT, TTMINHIWAT);
1867 tp->t_hiwat = roundup(x, CBSIZE);
1868 #undef CLAMP
1869 }
1870
1871 /*
1872 * Report on state of foreground process group.
1873 */
1874 void
1875 ttyinfo(tp)
1876 register struct tty *tp;
1877 {
1878 register struct proc *p, *pick;
1879 struct timeval utime, stime;
1880 int tmp;
1881
1882 if (ttycheckoutq(tp,0) == 0)
1883 return;
1884
1885 /* Print load average. */
1886 tmp = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT;
1887 ttyprintf(tp, "load: %d.%02d ", tmp / 100, tmp % 100);
1888
1889 if (tp->t_session == NULL)
1890 ttyprintf(tp, "not a controlling terminal\n");
1891 else if (tp->t_pgrp == NULL)
1892 ttyprintf(tp, "no foreground process group\n");
1893 else if ((p = tp->t_pgrp->pg_members.lh_first) == 0)
1894 ttyprintf(tp, "empty foreground process group\n");
1895 else {
1896 /* Pick interesting process. */
1897 for (pick = NULL; p != 0; p = p->p_pglist.le_next)
1898 if (proc_compare(pick, p))
1899 pick = p;
1900
1901 ttyprintf(tp, " cmd: %s %d [%s] ", pick->p_comm, pick->p_pid,
1902 pick->p_stat == SRUN ? "running" :
1903 pick->p_wmesg ? pick->p_wmesg : "iowait");
1904
1905 calcru(pick, &utime, &stime, NULL);
1906
1907 /* Round up and print user time. */
1908 utime.tv_usec += 5000;
1909 if (utime.tv_usec >= 1000000) {
1910 utime.tv_sec += 1;
1911 utime.tv_usec -= 1000000;
1912 }
1913 ttyprintf(tp, "%ld.%02ldu ", utime.tv_sec,
1914 utime.tv_usec / 10000);
1915
1916 /* Round up and print system time. */
1917 stime.tv_usec += 5000;
1918 if (stime.tv_usec >= 1000000) {
1919 stime.tv_sec += 1;
1920 stime.tv_usec -= 1000000;
1921 }
1922 ttyprintf(tp, "%ld.%02lds ", stime.tv_sec,
1923 stime.tv_usec / 10000);
1924
1925 #define pgtok(a) (((u_long) ((a) * NBPG) / 1024))
1926 /* Print percentage cpu, resident set size. */
1927 tmp = (pick->p_pctcpu * 10000 + FSCALE / 2) >> FSHIFT;
1928 ttyprintf(tp, "%d%% %ldk\n",
1929 tmp / 100,
1930 pick->p_stat == SIDL || pick->p_stat == SZOMB ? 0 :
1931 #ifdef pmap_resident_count
1932 pgtok(pmap_resident_count(&pick->p_vmspace->vm_pmap))
1933 #else
1934 pgtok(pick->p_vmspace->vm_rssize)
1935 #endif
1936 );
1937 }
1938 tp->t_rocount = 0; /* so pending input will be retyped if BS */
1939 }
1940
1941 /*
1942 * Returns 1 if p2 is "better" than p1
1943 *
1944 * The algorithm for picking the "interesting" process is thus:
1945 *
1946 * 1) Only foreground processes are eligible - implied.
1947 * 2) Runnable processes are favored over anything else. The runner
1948 * with the highest cpu utilization is picked (p_estcpu). Ties are
1949 * broken by picking the highest pid.
1950 * 3) The sleeper with the shortest sleep time is next. With ties,
1951 * we pick out just "short-term" sleepers (P_SINTR == 0).
1952 * 4) Further ties are broken by picking the highest pid.
1953 */
1954 #define ISRUN(p) (((p)->p_stat == SRUN) || ((p)->p_stat == SIDL))
1955 #define TESTAB(a, b) ((a)<<1 | (b))
1956 #define ONLYA 2
1957 #define ONLYB 1
1958 #define BOTH 3
1959
1960 static int
1961 proc_compare(p1, p2)
1962 register struct proc *p1, *p2;
1963 {
1964
1965 if (p1 == NULL)
1966 return (1);
1967 /*
1968 * see if at least one of them is runnable
1969 */
1970 switch (TESTAB(ISRUN(p1), ISRUN(p2))) {
1971 case ONLYA:
1972 return (0);
1973 case ONLYB:
1974 return (1);
1975 case BOTH:
1976 /*
1977 * tie - favor one with highest recent cpu utilization
1978 */
1979 if (p2->p_estcpu > p1->p_estcpu)
1980 return (1);
1981 if (p1->p_estcpu > p2->p_estcpu)
1982 return (0);
1983 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
1984 }
1985 /*
1986 * weed out zombies
1987 */
1988 switch (TESTAB(p1->p_stat == SZOMB, p2->p_stat == SZOMB)) {
1989 case ONLYA:
1990 return (1);
1991 case ONLYB:
1992 return (0);
1993 case BOTH:
1994 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
1995 }
1996 /*
1997 * pick the one with the smallest sleep time
1998 */
1999 if (p2->p_slptime > p1->p_slptime)
2000 return (0);
2001 if (p1->p_slptime > p2->p_slptime)
2002 return (1);
2003 /*
2004 * favor one sleeping in a non-interruptible sleep
2005 */
2006 if (p1->p_flag & P_SINTR && (p2->p_flag & P_SINTR) == 0)
2007 return (1);
2008 if (p2->p_flag & P_SINTR && (p1->p_flag & P_SINTR) == 0)
2009 return (0);
2010 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
2011 }
2012
2013 /*
2014 * Output char to tty; console putchar style.
2015 */
2016 int
2017 tputchar(c, tp)
2018 int c;
2019 struct tty *tp;
2020 {
2021 register int s;
2022
2023 s = spltty();
2024 if (ISSET(tp->t_state,
2025 TS_CARR_ON | TS_ISOPEN) != (TS_CARR_ON | TS_ISOPEN)) {
2026 splx(s);
2027 return (-1);
2028 }
2029 if (c == '\n')
2030 (void)ttyoutput('\r', tp);
2031 (void)ttyoutput(c, tp);
2032 ttstart(tp);
2033 splx(s);
2034 return (0);
2035 }
2036
2037 /*
2038 * Sleep on chan, returning ERESTART if tty changed while we napped and
2039 * returning any errors (e.g. EINTR/ETIMEDOUT) reported by tsleep. If
2040 * the tty is revoked, restarting a pending call will redo validation done
2041 * at the start of the call.
2042 */
2043 int
2044 ttysleep(tp, chan, pri, wmesg, timo)
2045 struct tty *tp;
2046 void *chan;
2047 int pri, timo;
2048 char *wmesg;
2049 {
2050 int error;
2051 short gen;
2052
2053 gen = tp->t_gen;
2054 if ((error = tsleep(chan, pri, wmesg, timo)) != 0)
2055 return (error);
2056 return (tp->t_gen == gen ? 0 : ERESTART);
2057 }
2058
2059 /*
2060 * Initialise the global tty list.
2061 */
2062 void
2063 tty_init()
2064 {
2065
2066 TAILQ_INIT(&ttylist);
2067 tty_count = 0;
2068 }
2069
2070 /*
2071 * Attach a tty to the tty list.
2072 *
2073 * This should be called ONLY once per real tty (including pty's).
2074 * eg, on the sparc, the keyboard and mouse have struct tty's that are
2075 * distinctly NOT usable as tty's, and thus should not be attached to
2076 * the ttylist. This is why this call is not done from ttymalloc().
2077 *
2078 * Device drivers should attach tty's at a similar time that they are
2079 * ttymalloc()'ed, or, for the case of statically allocated struct tty's
2080 * either in the attach or (first) open routine.
2081 */
2082 void
2083 tty_attach(tp)
2084 struct tty *tp;
2085 {
2086
2087 TAILQ_INSERT_TAIL(&ttylist, tp, tty_link);
2088 ++tty_count;
2089 }
2090
2091 /*
2092 * Remove a tty from the tty list.
2093 */
2094 void
2095 tty_detach(tp)
2096 struct tty *tp;
2097 {
2098
2099 --tty_count;
2100 #ifdef DIAGNOSTIC
2101 if (tty_count < 0)
2102 panic("tty_detach: tty_count < 0");
2103 #endif
2104 TAILQ_REMOVE(&ttylist, tp, tty_link);
2105 }
2106
2107 /*
2108 * Allocate a tty structure and its associated buffers.
2109 */
2110 struct tty *
2111 ttymalloc()
2112 {
2113 struct tty *tp;
2114
2115 MALLOC(tp, struct tty *, sizeof(struct tty), M_TTYS, M_WAITOK);
2116 bzero(tp, sizeof *tp);
2117 /* XXX: default to 1024 chars for now */
2118 clalloc(&tp->t_rawq, 1024, 1);
2119 clalloc(&tp->t_canq, 1024, 1);
2120 /* output queue doesn't need quoting */
2121 clalloc(&tp->t_outq, 1024, 0);
2122 return(tp);
2123 }
2124
2125 /*
2126 * Free a tty structure and its buffers.
2127 *
2128 * Be sure to call tty_detach() for any tty that has been
2129 * tty_attach()ed.
2130 */
2131 void
2132 ttyfree(tp)
2133 struct tty *tp;
2134 {
2135
2136 clfree(&tp->t_rawq);
2137 clfree(&tp->t_canq);
2138 clfree(&tp->t_outq);
2139 FREE(tp, M_TTYS);
2140 }
2141