tty.c revision 1.80 1 /* $NetBSD: tty.c,v 1.80 1997/04/02 03:23:01 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 * word erase (^W)
421 */
422 if (CCEQ(cc[VWERASE], c)) {
423 int alt = ISSET(lflag, ALTWERASE);
424 int ctype;
425
426 /*
427 * erase whitespace
428 */
429 while ((c = unputc(&tp->t_rawq)) == ' ' || c == '\t')
430 ttyrub(c, tp);
431 if (c == -1)
432 goto endcase;
433 /*
434 * erase last char of word and remember the
435 * next chars type (for ALTWERASE)
436 */
437 ttyrub(c, tp);
438 c = unputc(&tp->t_rawq);
439 if (c == -1)
440 goto endcase;
441 if (c == ' ' || c == '\t') {
442 (void)putc(c, &tp->t_rawq);
443 goto endcase;
444 }
445 ctype = ISALPHA(c);
446 /*
447 * erase rest of word
448 */
449 do {
450 ttyrub(c, tp);
451 c = unputc(&tp->t_rawq);
452 if (c == -1)
453 goto endcase;
454 } while (c != ' ' && c != '\t' &&
455 (alt == 0 || ISALPHA(c) == ctype));
456 (void)putc(c, &tp->t_rawq);
457 goto endcase;
458 }
459 /*
460 * reprint line (^R)
461 */
462 if (CCEQ(cc[VREPRINT], c)) {
463 ttyretype(tp);
464 goto endcase;
465 }
466 /*
467 * ^T - kernel info and generate SIGINFO
468 */
469 if (CCEQ(cc[VSTATUS], c)) {
470 if (ISSET(lflag, ISIG))
471 pgsignal(tp->t_pgrp, SIGINFO, 1);
472 if (!ISSET(lflag, NOKERNINFO))
473 ttyinfo(tp);
474 goto endcase;
475 }
476 }
477 /*
478 * Check for input buffer overflow
479 */
480 if (tp->t_rawq.c_cc + tp->t_canq.c_cc >= TTYHOG) {
481 if (ISSET(iflag, IMAXBEL)) {
482 if (tp->t_outq.c_cc < tp->t_hiwat)
483 (void)ttyoutput(CTRL('g'), tp);
484 } else
485 ttyflush(tp, FREAD | FWRITE);
486 goto endcase;
487 }
488 /*
489 * Put data char in q for user and
490 * wakeup on seeing a line delimiter.
491 */
492 if (putc(c, &tp->t_rawq) >= 0) {
493 if (!ISSET(lflag, ICANON)) {
494 ttwakeup(tp);
495 ttyecho(c, tp);
496 goto endcase;
497 }
498 if (TTBREAKC(c)) {
499 tp->t_rocount = 0;
500 catq(&tp->t_rawq, &tp->t_canq);
501 ttwakeup(tp);
502 } else if (tp->t_rocount++ == 0)
503 tp->t_rocol = tp->t_column;
504 if (ISSET(tp->t_state, TS_ERASE)) {
505 /*
506 * end of prterase \.../
507 */
508 CLR(tp->t_state, TS_ERASE);
509 (void)ttyoutput('/', tp);
510 }
511 i = tp->t_column;
512 ttyecho(c, tp);
513 if (CCEQ(cc[VEOF], c) && ISSET(lflag, ECHO)) {
514 /*
515 * Place the cursor over the '^' of the ^D.
516 */
517 i = min(2, tp->t_column - i);
518 while (i > 0) {
519 (void)ttyoutput('\b', tp);
520 i--;
521 }
522 }
523 }
524 endcase:
525 /*
526 * IXANY means allow any character to restart output.
527 */
528 if (ISSET(tp->t_state, TS_TTSTOP) &&
529 !ISSET(iflag, IXANY) && cc[VSTART] != cc[VSTOP])
530 return (0);
531 restartoutput:
532 CLR(tp->t_lflag, FLUSHO);
533 CLR(tp->t_state, TS_TTSTOP);
534 startoutput:
535 return (ttstart(tp));
536 }
537
538 /*
539 * Output a single character on a tty, doing output processing
540 * as needed (expanding tabs, newline processing, etc.).
541 * Returns < 0 if succeeds, otherwise returns char to resend.
542 * Must be recursive.
543 */
544 int
545 ttyoutput(c, tp)
546 register int c;
547 register struct tty *tp;
548 {
549 register long oflag;
550 register int col, notout, s;
551
552 oflag = tp->t_oflag;
553 if (!ISSET(oflag, OPOST)) {
554 if (ISSET(tp->t_lflag, FLUSHO))
555 return (-1);
556 if (putc(c, &tp->t_outq))
557 return (c);
558 tk_nout++;
559 tp->t_outcc++;
560 return (-1);
561 }
562 /*
563 * Do tab expansion if OXTABS is set. Special case if we external
564 * processing, we don't do the tab expansion because we'll probably
565 * get it wrong. If tab expansion needs to be done, let it happen
566 * externally.
567 */
568 CLR(c, ~TTY_CHARMASK);
569 if (c == '\t' &&
570 ISSET(oflag, OXTABS) && !ISSET(tp->t_lflag, EXTPROC)) {
571 c = 8 - (tp->t_column & 7);
572 if (ISSET(tp->t_lflag, FLUSHO)) {
573 notout = 0;
574 } else {
575 s = spltty(); /* Don't interrupt tabs. */
576 notout = b_to_q(" ", c, &tp->t_outq);
577 c -= notout;
578 tk_nout += c;
579 tp->t_outcc += c;
580 splx(s);
581 }
582 tp->t_column += c;
583 return (notout ? '\t' : -1);
584 }
585 if (c == CEOT && ISSET(oflag, ONOEOT))
586 return (-1);
587
588 /*
589 * Newline translation: if ONLCR is set,
590 * translate newline into "\r\n".
591 */
592 if (c == '\n' && ISSET(tp->t_oflag, ONLCR)) {
593 tk_nout++;
594 tp->t_outcc++;
595 if (putc('\r', &tp->t_outq))
596 return (c);
597 }
598 /*
599 * If OCRNL is set, translate "\r" into "\n".
600 */
601 else if (c == '\r' && ISSET(tp->t_oflag, OCRNL))
602 c = '\n';
603
604 tk_nout++;
605 tp->t_outcc++;
606 if (!ISSET(tp->t_lflag, FLUSHO) && putc(c, &tp->t_outq))
607 return (c);
608
609 col = tp->t_column;
610 switch (CCLASS(c)) {
611 case BACKSPACE:
612 if (col > 0)
613 --col;
614 break;
615 case CONTROL:
616 break;
617 case NEWLINE:
618 if (ISSET(tp->t_oflag, OCRNL))
619 col = 0;
620 break;
621 case RETURN:
622 col = 0;
623 break;
624 case ORDINARY:
625 ++col;
626 break;
627 case TAB:
628 col = (col + 8) & ~7;
629 break;
630 }
631 tp->t_column = col;
632 return (-1);
633 }
634
635 /*
636 * Ioctls for all tty devices. Called after line-discipline specific ioctl
637 * has been called to do discipline-specific functions and/or reject any
638 * of these ioctl commands.
639 */
640 /* ARGSUSED */
641 int
642 ttioctl(tp, cmd, data, flag, p)
643 register struct tty *tp;
644 u_long cmd;
645 caddr_t data;
646 int flag;
647 struct proc *p;
648 {
649 extern struct tty *constty; /* Temporary virtual console. */
650 extern int nlinesw;
651 int s, error;
652
653 /* If the ioctl involves modification, hang if in the background. */
654 switch (cmd) {
655 case TIOCFLUSH:
656 case TIOCSETA:
657 case TIOCSETD:
658 case TIOCSETAF:
659 case TIOCSETAW:
660 #ifdef notdef
661 case TIOCSPGRP:
662 #endif
663 case TIOCSTAT:
664 case TIOCSTI:
665 case TIOCSWINSZ:
666 #ifdef COMPAT_OLDTTY
667 case TIOCLBIC:
668 case TIOCLBIS:
669 case TIOCLSET:
670 case TIOCSETC:
671 case OTIOCSETD:
672 case TIOCSETN:
673 case TIOCSETP:
674 case TIOCSLTC:
675 #endif
676 while (isbackground(curproc, tp) &&
677 p->p_pgrp->pg_jobc && (p->p_flag & P_PPWAIT) == 0 &&
678 (p->p_sigignore & sigmask(SIGTTOU)) == 0 &&
679 (p->p_sigmask & sigmask(SIGTTOU)) == 0) {
680 pgsignal(p->p_pgrp, SIGTTOU, 1);
681 error = ttysleep(tp,
682 &lbolt, TTOPRI | PCATCH, ttybg, 0);
683 if (error)
684 return (error);
685 }
686 break;
687 }
688
689 switch (cmd) { /* Process the ioctl. */
690 case FIOASYNC: /* set/clear async i/o */
691 s = spltty();
692 if (*(int *)data)
693 SET(tp->t_state, TS_ASYNC);
694 else
695 CLR(tp->t_state, TS_ASYNC);
696 splx(s);
697 break;
698 case FIONBIO: /* set/clear non-blocking i/o */
699 break; /* XXX: delete. */
700 case FIONREAD: /* get # bytes to read */
701 *(int *)data = ttnread(tp);
702 break;
703 case TIOCEXCL: /* set exclusive use of tty */
704 s = spltty();
705 SET(tp->t_state, TS_XCLUDE);
706 splx(s);
707 break;
708 case TIOCFLUSH: { /* flush buffers */
709 register int flags = *(int *)data;
710
711 if (flags == 0)
712 flags = FREAD | FWRITE;
713 else
714 flags &= FREAD | FWRITE;
715 ttyflush(tp, flags);
716 break;
717 }
718 case TIOCCONS: /* become virtual console */
719 if (*(int *)data) {
720 if (constty && constty != tp &&
721 ISSET(constty->t_state, TS_CARR_ON | TS_ISOPEN) ==
722 (TS_CARR_ON | TS_ISOPEN))
723 return (EBUSY);
724 #ifndef UCONSOLE
725 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
726 return (error);
727 #endif
728 constty = tp;
729 } else if (tp == constty)
730 constty = NULL;
731 break;
732 case TIOCDRAIN: /* wait till output drained */
733 if ((error = ttywait(tp)) != 0)
734 return (error);
735 break;
736 case TIOCGETA: { /* get termios struct */
737 struct termios *t = (struct termios *)data;
738
739 bcopy(&tp->t_termios, t, sizeof(struct termios));
740 break;
741 }
742 case TIOCGETD: /* get line discipline */
743 *(int *)data = tp->t_line;
744 break;
745 case TIOCGWINSZ: /* get window size */
746 *(struct winsize *)data = tp->t_winsize;
747 break;
748 case TIOCGPGRP: /* get pgrp of tty */
749 if (!isctty(p, tp))
750 return (ENOTTY);
751 *(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
752 break;
753 #ifdef TIOCHPCL
754 case TIOCHPCL: /* hang up on last close */
755 s = spltty();
756 SET(tp->t_cflag, HUPCL);
757 splx(s);
758 break;
759 #endif
760 case TIOCNXCL: /* reset exclusive use of tty */
761 s = spltty();
762 CLR(tp->t_state, TS_XCLUDE);
763 splx(s);
764 break;
765 case TIOCOUTQ: /* output queue size */
766 *(int *)data = tp->t_outq.c_cc;
767 break;
768 case TIOCSETA: /* set termios struct */
769 case TIOCSETAW: /* drain output, set */
770 case TIOCSETAF: { /* drn out, fls in, set */
771 register struct termios *t = (struct termios *)data;
772
773 s = spltty();
774 if (cmd == TIOCSETAW || cmd == TIOCSETAF) {
775 if ((error = ttywait(tp)) != 0) {
776 splx(s);
777 return (error);
778 }
779 if (cmd == TIOCSETAF)
780 ttyflush(tp, FREAD);
781 }
782 if (!ISSET(t->c_cflag, CIGNORE)) {
783 /*
784 * Set device hardware.
785 */
786 if (tp->t_param && (error = (*tp->t_param)(tp, t))) {
787 splx(s);
788 return (error);
789 } else {
790 if (!ISSET(tp->t_state, TS_CARR_ON) &&
791 ISSET(tp->t_cflag, CLOCAL) &&
792 !ISSET(t->c_cflag, CLOCAL)) {
793 CLR(tp->t_state, TS_ISOPEN);
794 SET(tp->t_state, TS_WOPEN);
795 ttwakeup(tp);
796 }
797 tp->t_cflag = t->c_cflag;
798 tp->t_ispeed = t->c_ispeed;
799 tp->t_ospeed = t->c_ospeed;
800 if (t->c_ospeed == 0 && tp->t_session &&
801 tp->t_session->s_leader)
802 psignal(tp->t_session->s_leader,
803 SIGHUP);
804 }
805 ttsetwater(tp);
806 }
807 if (cmd != TIOCSETAF) {
808 if (ISSET(t->c_lflag, ICANON) !=
809 ISSET(tp->t_lflag, ICANON))
810 if (ISSET(t->c_lflag, ICANON)) {
811 SET(tp->t_lflag, PENDIN);
812 ttwakeup(tp);
813 } else {
814 struct clist tq;
815
816 catq(&tp->t_rawq, &tp->t_canq);
817 tq = tp->t_rawq;
818 tp->t_rawq = tp->t_canq;
819 tp->t_canq = tq;
820 CLR(tp->t_lflag, PENDIN);
821 }
822 }
823 tp->t_iflag = t->c_iflag;
824 tp->t_oflag = t->c_oflag;
825 /*
826 * Make the EXTPROC bit read only.
827 */
828 if (ISSET(tp->t_lflag, EXTPROC))
829 SET(t->c_lflag, EXTPROC);
830 else
831 CLR(t->c_lflag, EXTPROC);
832 tp->t_lflag = t->c_lflag | ISSET(tp->t_lflag, PENDIN);
833 bcopy(t->c_cc, tp->t_cc, sizeof(t->c_cc));
834 splx(s);
835 break;
836 }
837 case TIOCSETD: { /* set line discipline */
838 register int t = *(int *)data;
839 dev_t device = tp->t_dev;
840
841 if ((u_int)t >= nlinesw)
842 return (ENXIO);
843 if (t != tp->t_line) {
844 s = spltty();
845 (*linesw[tp->t_line].l_close)(tp, flag);
846 error = (*linesw[t].l_open)(device, tp);
847 if (error) {
848 (void)(*linesw[tp->t_line].l_open)(device, tp);
849 splx(s);
850 return (error);
851 }
852 tp->t_line = t;
853 splx(s);
854 }
855 break;
856 }
857 case TIOCSTART: /* start output, like ^Q */
858 s = spltty();
859 if (ISSET(tp->t_state, TS_TTSTOP) ||
860 ISSET(tp->t_lflag, FLUSHO)) {
861 CLR(tp->t_lflag, FLUSHO);
862 CLR(tp->t_state, TS_TTSTOP);
863 ttstart(tp);
864 }
865 splx(s);
866 break;
867 case TIOCSTI: /* simulate terminal input */
868 if (p->p_ucred->cr_uid && (flag & FREAD) == 0)
869 return (EPERM);
870 if (p->p_ucred->cr_uid && !isctty(p, tp))
871 return (EACCES);
872 (*linesw[tp->t_line].l_rint)(*(u_char *)data, tp);
873 break;
874 case TIOCSTOP: /* stop output, like ^S */
875 s = spltty();
876 if (!ISSET(tp->t_state, TS_TTSTOP)) {
877 SET(tp->t_state, TS_TTSTOP);
878 (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
879 }
880 splx(s);
881 break;
882 case TIOCSCTTY: /* become controlling tty */
883 /* Session ctty vnode pointer set in vnode layer. */
884 if (!SESS_LEADER(p) ||
885 ((p->p_session->s_ttyvp || tp->t_session) &&
886 (tp->t_session != p->p_session)))
887 return (EPERM);
888 tp->t_session = p->p_session;
889 tp->t_pgrp = p->p_pgrp;
890 p->p_session->s_ttyp = tp;
891 p->p_flag |= P_CONTROLT;
892 break;
893 case TIOCSPGRP: { /* set pgrp of tty */
894 register struct pgrp *pgrp = pgfind(*(int *)data);
895
896 if (!isctty(p, tp))
897 return (ENOTTY);
898 else if (pgrp == NULL || pgrp->pg_session != p->p_session)
899 return (EPERM);
900 tp->t_pgrp = pgrp;
901 break;
902 }
903 case TIOCSTAT: /* get load avg stats */
904 ttyinfo(tp);
905 break;
906 case TIOCSWINSZ: /* set window size */
907 if (bcmp((caddr_t)&tp->t_winsize, data,
908 sizeof (struct winsize))) {
909 tp->t_winsize = *(struct winsize *)data;
910 pgsignal(tp->t_pgrp, SIGWINCH, 1);
911 }
912 break;
913 default:
914 #ifdef COMPAT_OLDTTY
915 return (ttcompat(tp, cmd, data, flag, p));
916 #else
917 return (-1);
918 #endif
919 }
920 return (0);
921 }
922
923 int
924 ttpoll(dev, events, p)
925 dev_t dev;
926 int events;
927 struct proc *p;
928 {
929 register struct tty *tp = (*cdevsw[major(dev)].d_tty)(dev);
930 int revents = 0;
931 int s = spltty();
932
933 if (events & (POLLIN | POLLRDNORM))
934 if (ttnread(tp) > 0)
935 revents |= events & (POLLIN | POLLRDNORM);
936
937 if (events & (POLLOUT | POLLWRNORM))
938 if (tp->t_outq.c_cc <= tp->t_lowat)
939 revents |= events & (POLLOUT | POLLWRNORM);
940
941 if (events & POLLHUP)
942 if (!ISSET(tp->t_cflag, CLOCAL) &&
943 !ISSET(tp->t_state, TS_CARR_ON))
944 revents |= POLLHUP;
945
946 if (revents == 0) {
947 if (events & (POLLIN | POLLHUP | POLLRDNORM))
948 selrecord(p, &tp->t_rsel);
949
950 if (events & (POLLOUT | POLLWRNORM))
951 selrecord(p, &tp->t_wsel);
952 }
953
954 splx(s);
955 return (revents);
956 }
957
958 static int
959 ttnread(tp)
960 struct tty *tp;
961 {
962 int nread;
963
964 if (ISSET(tp->t_lflag, PENDIN))
965 ttypend(tp);
966 nread = tp->t_canq.c_cc;
967 if (!ISSET(tp->t_lflag, ICANON)) {
968 nread += tp->t_rawq.c_cc;
969 if (nread < tp->t_cc[VMIN] && !tp->t_cc[VTIME])
970 nread = 0;
971 }
972 return (nread);
973 }
974
975 /*
976 * Wait for output to drain.
977 */
978 int
979 ttywait(tp)
980 register struct tty *tp;
981 {
982 int error, s;
983
984 error = 0;
985 s = spltty();
986 while ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
987 (ISSET(tp->t_state, TS_CARR_ON) || ISSET(tp->t_cflag, CLOCAL))
988 && tp->t_oproc) {
989 (*tp->t_oproc)(tp);
990 SET(tp->t_state, TS_ASLEEP);
991 error = ttysleep(tp, &tp->t_outq, TTOPRI | PCATCH, ttyout, 0);
992 if (error)
993 break;
994 }
995 splx(s);
996 return (error);
997 }
998
999 /*
1000 * Flush if successfully wait.
1001 */
1002 int
1003 ttywflush(tp)
1004 struct tty *tp;
1005 {
1006 int error;
1007
1008 if ((error = ttywait(tp)) == 0)
1009 ttyflush(tp, FREAD);
1010 return (error);
1011 }
1012
1013 /*
1014 * Flush tty read and/or write queues, notifying anyone waiting.
1015 */
1016 void
1017 ttyflush(tp, rw)
1018 register struct tty *tp;
1019 int rw;
1020 {
1021 register int s;
1022
1023 s = spltty();
1024 if (rw & FREAD) {
1025 FLUSHQ(&tp->t_canq);
1026 FLUSHQ(&tp->t_rawq);
1027 tp->t_rocount = 0;
1028 tp->t_rocol = 0;
1029 CLR(tp->t_state, TS_LOCAL);
1030 ttwakeup(tp);
1031 }
1032 if (rw & FWRITE) {
1033 CLR(tp->t_state, TS_TTSTOP);
1034 (*cdevsw[major(tp->t_dev)].d_stop)(tp, rw);
1035 FLUSHQ(&tp->t_outq);
1036 wakeup((caddr_t)&tp->t_outq);
1037 selwakeup(&tp->t_wsel);
1038 }
1039 splx(s);
1040 }
1041
1042 /*
1043 * Copy in the default termios characters.
1044 */
1045 void
1046 ttychars(tp)
1047 struct tty *tp;
1048 {
1049
1050 bcopy(ttydefchars, tp->t_cc, sizeof(ttydefchars));
1051 }
1052
1053 /*
1054 * Send stop character on input overflow.
1055 */
1056 static void
1057 ttyblock(tp)
1058 register struct tty *tp;
1059 {
1060 register int total;
1061
1062 total = tp->t_rawq.c_cc + tp->t_canq.c_cc;
1063 if (tp->t_rawq.c_cc > TTYHOG) {
1064 ttyflush(tp, FREAD | FWRITE);
1065 CLR(tp->t_state, TS_TBLOCK);
1066 }
1067 /*
1068 * Block further input iff: current input > threshold
1069 * AND input is available to user program.
1070 */
1071 if ((total >= TTYHOG / 2 &&
1072 !ISSET(tp->t_state, TS_TBLOCK) &&
1073 !ISSET(tp->t_lflag, ICANON)) || tp->t_canq.c_cc > 0) {
1074 if (ISSET(tp->t_iflag, IXOFF) &&
1075 tp->t_cc[VSTOP] != _POSIX_VDISABLE &&
1076 putc(tp->t_cc[VSTOP], &tp->t_outq) == 0) {
1077 SET(tp->t_state, TS_TBLOCK);
1078 ttstart(tp);
1079 }
1080 /* Try to block remote output via hardware flow control. */
1081 if (ISSET(tp->t_cflag, CHWFLOW) && tp->t_hwiflow &&
1082 (*tp->t_hwiflow)(tp, 1) != 0)
1083 SET(tp->t_state, TS_TBLOCK);
1084 }
1085 }
1086
1087 void
1088 ttrstrt(tp_arg)
1089 void *tp_arg;
1090 {
1091 struct tty *tp;
1092 int s;
1093
1094 #ifdef DIAGNOSTIC
1095 if (tp_arg == NULL)
1096 panic("ttrstrt");
1097 #endif
1098 tp = tp_arg;
1099 s = spltty();
1100
1101 CLR(tp->t_state, TS_TIMEOUT);
1102 ttstart(tp);
1103
1104 splx(s);
1105 }
1106
1107 int
1108 ttstart(tp)
1109 struct tty *tp;
1110 {
1111
1112 if (tp->t_oproc != NULL) /* XXX: Kludge for pty. */
1113 (*tp->t_oproc)(tp);
1114 return (0);
1115 }
1116
1117 /*
1118 * "close" a line discipline
1119 */
1120 int
1121 ttylclose(tp, flag)
1122 struct tty *tp;
1123 int flag;
1124 {
1125
1126 if (flag & FNONBLOCK)
1127 ttyflush(tp, FREAD | FWRITE);
1128 else
1129 ttywflush(tp);
1130 return (0);
1131 }
1132
1133 /*
1134 * Handle modem control transition on a tty.
1135 * Flag indicates new state of carrier.
1136 * Returns 0 if the line should be turned off, otherwise 1.
1137 */
1138 int
1139 ttymodem(tp, flag)
1140 register struct tty *tp;
1141 int flag;
1142 {
1143
1144 if (!ISSET(tp->t_state, TS_WOPEN) && ISSET(tp->t_cflag, MDMBUF)) {
1145 /*
1146 * MDMBUF: do flow control according to carrier flag
1147 */
1148 if (flag) {
1149 CLR(tp->t_state, TS_TTSTOP);
1150 ttstart(tp);
1151 } else if (!ISSET(tp->t_state, TS_TTSTOP)) {
1152 SET(tp->t_state, TS_TTSTOP);
1153 (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
1154 }
1155 } else if (flag == 0) {
1156 /*
1157 * Lost carrier.
1158 */
1159 CLR(tp->t_state, TS_CARR_ON);
1160 if (ISSET(tp->t_state, TS_ISOPEN) &&
1161 !ISSET(tp->t_cflag, CLOCAL)) {
1162 if (tp->t_session && tp->t_session->s_leader)
1163 psignal(tp->t_session->s_leader, SIGHUP);
1164 ttyflush(tp, FREAD | FWRITE);
1165 return (0);
1166 }
1167 } else {
1168 /*
1169 * Carrier now on.
1170 */
1171 SET(tp->t_state, TS_CARR_ON);
1172 ttwakeup(tp);
1173 }
1174 return (1);
1175 }
1176
1177 /*
1178 * Default modem control routine (for other line disciplines).
1179 * Return argument flag, to turn off device on carrier drop.
1180 */
1181 int
1182 nullmodem(tp, flag)
1183 register struct tty *tp;
1184 int flag;
1185 {
1186
1187 if (flag)
1188 SET(tp->t_state, TS_CARR_ON);
1189 else {
1190 CLR(tp->t_state, TS_CARR_ON);
1191 if (!ISSET(tp->t_cflag, CLOCAL)) {
1192 if (tp->t_session && tp->t_session->s_leader)
1193 psignal(tp->t_session->s_leader, SIGHUP);
1194 return (0);
1195 }
1196 }
1197 return (1);
1198 }
1199
1200 /*
1201 * Reinput pending characters after state switch
1202 * call at spltty().
1203 */
1204 void
1205 ttypend(tp)
1206 register struct tty *tp;
1207 {
1208 struct clist tq;
1209 register c;
1210
1211 CLR(tp->t_lflag, PENDIN);
1212 SET(tp->t_state, TS_TYPEN);
1213 tq = tp->t_rawq;
1214 tp->t_rawq.c_cc = 0;
1215 tp->t_rawq.c_cf = tp->t_rawq.c_cl = 0;
1216 while ((c = getc(&tq)) >= 0)
1217 ttyinput(c, tp);
1218 CLR(tp->t_state, TS_TYPEN);
1219 }
1220
1221 /*
1222 * Process a read call on a tty device.
1223 */
1224 int
1225 ttread(tp, uio, flag)
1226 register struct tty *tp;
1227 struct uio *uio;
1228 int flag;
1229 {
1230 register struct clist *qp;
1231 register int c;
1232 register long lflag;
1233 register u_char *cc = tp->t_cc;
1234 register struct proc *p = curproc;
1235 int s, first, error = 0;
1236 struct timeval stime;
1237 int has_stime = 0, last_cc = 0;
1238 long slp = 0;
1239
1240 loop: lflag = tp->t_lflag;
1241 s = spltty();
1242 /*
1243 * take pending input first
1244 */
1245 if (ISSET(lflag, PENDIN))
1246 ttypend(tp);
1247 splx(s);
1248
1249 /*
1250 * Hang process if it's in the background.
1251 */
1252 if (isbackground(p, tp)) {
1253 if ((p->p_sigignore & sigmask(SIGTTIN)) ||
1254 (p->p_sigmask & sigmask(SIGTTIN)) ||
1255 p->p_flag & P_PPWAIT || p->p_pgrp->pg_jobc == 0)
1256 return (EIO);
1257 pgsignal(p->p_pgrp, SIGTTIN, 1);
1258 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, ttybg, 0);
1259 if (error)
1260 return (error);
1261 goto loop;
1262 }
1263
1264 s = spltty();
1265 if (!ISSET(lflag, ICANON)) {
1266 int m = cc[VMIN];
1267 long t = cc[VTIME];
1268
1269 qp = &tp->t_rawq;
1270 /*
1271 * Check each of the four combinations.
1272 * (m > 0 && t == 0) is the normal read case.
1273 * It should be fairly efficient, so we check that and its
1274 * companion case (m == 0 && t == 0) first.
1275 * For the other two cases, we compute the target sleep time
1276 * into slp.
1277 */
1278 if (t == 0) {
1279 if (qp->c_cc < m)
1280 goto sleep;
1281 goto read;
1282 }
1283 t *= 100000; /* time in us */
1284 #define diff(t1, t2) (((t1).tv_sec - (t2).tv_sec) * 1000000 + \
1285 ((t1).tv_usec - (t2).tv_usec))
1286 if (m > 0) {
1287 if (qp->c_cc <= 0)
1288 goto sleep;
1289 if (qp->c_cc >= m)
1290 goto read;
1291 if (!has_stime) {
1292 /* first character, start timer */
1293 has_stime = 1;
1294 stime = time;
1295 slp = t;
1296 } else if (qp->c_cc > last_cc) {
1297 /* got a character, restart timer */
1298 stime = time;
1299 slp = t;
1300 } else {
1301 /* nothing, check expiration */
1302 slp = t - diff(time, stime);
1303 }
1304 } else { /* m == 0 */
1305 if (qp->c_cc > 0)
1306 goto read;
1307 if (!has_stime) {
1308 has_stime = 1;
1309 stime = time;
1310 slp = t;
1311 } else
1312 slp = t - diff(time, stime);
1313 }
1314 last_cc = qp->c_cc;
1315 #undef diff
1316 if (slp > 0) {
1317 /*
1318 * Rounding down may make us wake up just short
1319 * of the target, so we round up.
1320 * The formula is ceiling(slp * hz/1000000).
1321 * 32-bit arithmetic is enough for hz < 169.
1322 *
1323 * Also, use plain wakeup() not ttwakeup().
1324 */
1325 slp = (long) (((u_long)slp * hz) + 999999) / 1000000;
1326 goto sleep;
1327 }
1328 } else if ((qp = &tp->t_canq)->c_cc <= 0) {
1329 int carrier;
1330
1331 sleep:
1332 /*
1333 * If there is no input, sleep on rawq
1334 * awaiting hardware receipt and notification.
1335 * If we have data, we don't need to check for carrier.
1336 */
1337 carrier = ISSET(tp->t_state, TS_CARR_ON) ||
1338 ISSET(tp->t_cflag, CLOCAL);
1339 if (!carrier && ISSET(tp->t_state, TS_ISOPEN)) {
1340 splx(s);
1341 return (0); /* EOF */
1342 }
1343 if (flag & IO_NDELAY) {
1344 splx(s);
1345 return (EWOULDBLOCK);
1346 }
1347 error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH,
1348 carrier ? ttyin : ttopen, slp);
1349 splx(s);
1350 if (error && error != EWOULDBLOCK)
1351 return (error);
1352 goto loop;
1353 }
1354 read:
1355 splx(s);
1356
1357 /*
1358 * Input present, check for input mapping and processing.
1359 */
1360 first = 1;
1361 while ((c = getc(qp)) >= 0) {
1362 /*
1363 * delayed suspend (^Y)
1364 */
1365 if (CCEQ(cc[VDSUSP], c) && ISSET(lflag, ISIG)) {
1366 pgsignal(tp->t_pgrp, SIGTSTP, 1);
1367 if (first) {
1368 error = ttysleep(tp, &lbolt,
1369 TTIPRI | PCATCH, ttybg, 0);
1370 if (error)
1371 break;
1372 goto loop;
1373 }
1374 break;
1375 }
1376 /*
1377 * Interpret EOF only in canonical mode.
1378 */
1379 if (CCEQ(cc[VEOF], c) && ISSET(lflag, ICANON))
1380 break;
1381 /*
1382 * Give user character.
1383 */
1384 error = ureadc(c, uio);
1385 if (error)
1386 break;
1387 if (uio->uio_resid == 0)
1388 break;
1389 /*
1390 * In canonical mode check for a "break character"
1391 * marking the end of a "line of input".
1392 */
1393 if (ISSET(lflag, ICANON) && TTBREAKC(c))
1394 break;
1395 first = 0;
1396 }
1397 /*
1398 * Look to unblock output now that (presumably)
1399 * the input queue has gone down.
1400 */
1401 s = spltty();
1402 if (ISSET(tp->t_state, TS_TBLOCK) && tp->t_rawq.c_cc < TTYHOG/5) {
1403 if (ISSET(tp->t_iflag, IXOFF) &&
1404 cc[VSTART] != _POSIX_VDISABLE &&
1405 putc(cc[VSTART], &tp->t_outq) == 0) {
1406 CLR(tp->t_state, TS_TBLOCK);
1407 ttstart(tp);
1408 }
1409 /* Try to unblock remote output via hardware flow control. */
1410 if (ISSET(tp->t_cflag, CHWFLOW) && tp->t_hwiflow &&
1411 (*tp->t_hwiflow)(tp, 0) != 0)
1412 CLR(tp->t_state, TS_TBLOCK);
1413 }
1414 splx(s);
1415 return (error);
1416 }
1417
1418 /*
1419 * Check the output queue on tp for space for a kernel message (from uprintf
1420 * or tprintf). Allow some space over the normal hiwater mark so we don't
1421 * lose messages due to normal flow control, but don't let the tty run amok.
1422 * Sleeps here are not interruptible, but we return prematurely if new signals
1423 * arrive.
1424 */
1425 int
1426 ttycheckoutq(tp, wait)
1427 register struct tty *tp;
1428 int wait;
1429 {
1430 int hiwat, s, oldsig;
1431
1432 hiwat = tp->t_hiwat;
1433 s = spltty();
1434 oldsig = wait ? curproc->p_siglist : 0;
1435 if (tp->t_outq.c_cc > hiwat + 200)
1436 while (tp->t_outq.c_cc > hiwat) {
1437 ttstart(tp);
1438 if (wait == 0 || curproc->p_siglist != oldsig) {
1439 splx(s);
1440 return (0);
1441 }
1442 timeout((void (*)__P((void *)))wakeup,
1443 (void *)&tp->t_outq, hz);
1444 SET(tp->t_state, TS_ASLEEP);
1445 tsleep(&tp->t_outq, PZERO - 1, "ttckoutq", 0);
1446 }
1447 splx(s);
1448 return (1);
1449 }
1450
1451 /*
1452 * Process a write call on a tty device.
1453 */
1454 int
1455 ttwrite(tp, uio, flag)
1456 register struct tty *tp;
1457 register struct uio *uio;
1458 int flag;
1459 {
1460 register u_char *cp = NULL;
1461 register int cc, ce;
1462 register struct proc *p;
1463 int i, hiwat, cnt, error, s;
1464 u_char obuf[OBUFSIZ];
1465
1466 hiwat = tp->t_hiwat;
1467 cnt = uio->uio_resid;
1468 error = 0;
1469 cc = 0;
1470 loop:
1471 s = spltty();
1472 if (!ISSET(tp->t_state, TS_CARR_ON) &&
1473 !ISSET(tp->t_cflag, CLOCAL)) {
1474 if (ISSET(tp->t_state, TS_ISOPEN)) {
1475 splx(s);
1476 return (EIO);
1477 } else if (flag & IO_NDELAY) {
1478 splx(s);
1479 error = EWOULDBLOCK;
1480 goto out;
1481 } else {
1482 /* Sleep awaiting carrier. */
1483 error = ttysleep(tp,
1484 &tp->t_rawq, TTIPRI | PCATCH, ttopen, 0);
1485 splx(s);
1486 if (error)
1487 goto out;
1488 goto loop;
1489 }
1490 }
1491 splx(s);
1492 /*
1493 * Hang the process if it's in the background.
1494 */
1495 p = curproc;
1496 if (isbackground(p, tp) &&
1497 ISSET(tp->t_lflag, TOSTOP) && (p->p_flag & P_PPWAIT) == 0 &&
1498 (p->p_sigignore & sigmask(SIGTTOU)) == 0 &&
1499 (p->p_sigmask & sigmask(SIGTTOU)) == 0 &&
1500 p->p_pgrp->pg_jobc) {
1501 pgsignal(p->p_pgrp, SIGTTOU, 1);
1502 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, ttybg, 0);
1503 if (error)
1504 goto out;
1505 goto loop;
1506 }
1507 /*
1508 * Process the user's data in at most OBUFSIZ chunks. Perform any
1509 * output translation. Keep track of high water mark, sleep on
1510 * overflow awaiting device aid in acquiring new space.
1511 */
1512 while (uio->uio_resid > 0 || cc > 0) {
1513 if (ISSET(tp->t_lflag, FLUSHO)) {
1514 uio->uio_resid = 0;
1515 return (0);
1516 }
1517 if (tp->t_outq.c_cc > hiwat)
1518 goto ovhiwat;
1519 /*
1520 * Grab a hunk of data from the user, unless we have some
1521 * leftover from last time.
1522 */
1523 if (cc == 0) {
1524 cc = min(uio->uio_resid, OBUFSIZ);
1525 cp = obuf;
1526 error = uiomove(cp, cc, uio);
1527 if (error) {
1528 cc = 0;
1529 break;
1530 }
1531 }
1532 /*
1533 * If nothing fancy need be done, grab those characters we
1534 * can handle without any of ttyoutput's processing and
1535 * just transfer them to the output q. For those chars
1536 * which require special processing (as indicated by the
1537 * bits in char_type), call ttyoutput. After processing
1538 * a hunk of data, look for FLUSHO so ^O's will take effect
1539 * immediately.
1540 */
1541 while (cc > 0) {
1542 if (!ISSET(tp->t_oflag, OPOST))
1543 ce = cc;
1544 else {
1545 ce = cc - scanc((u_int)cc, cp, char_type,
1546 CCLASSMASK);
1547 /*
1548 * If ce is zero, then we're processing
1549 * a special character through ttyoutput.
1550 */
1551 if (ce == 0) {
1552 tp->t_rocount = 0;
1553 if (ttyoutput(*cp, tp) >= 0) {
1554 #ifdef REAL_CLISTS
1555 /* No Clists, wait a bit. */
1556 ttstart(tp);
1557 if (error = ttysleep(tp, &lbolt,
1558 TTOPRI | PCATCH, ttybuf, 0))
1559 break;
1560 goto loop;
1561 #else
1562 /* out of space */
1563 goto overfull;
1564 #endif
1565 }
1566 cp++;
1567 cc--;
1568 if (ISSET(tp->t_lflag, FLUSHO) ||
1569 tp->t_outq.c_cc > hiwat)
1570 goto ovhiwat;
1571 continue;
1572 }
1573 }
1574 /*
1575 * A bunch of normal characters have been found.
1576 * Transfer them en masse to the output queue and
1577 * continue processing at the top of the loop.
1578 * If there are any further characters in this
1579 * <= OBUFSIZ chunk, the first should be a character
1580 * requiring special handling by ttyoutput.
1581 */
1582 tp->t_rocount = 0;
1583 i = b_to_q(cp, ce, &tp->t_outq);
1584 ce -= i;
1585 tp->t_column += ce;
1586 cp += ce, cc -= ce, tk_nout += ce;
1587 tp->t_outcc += ce;
1588 if (i > 0) {
1589 #ifdef REAL_CLISTS
1590 /* No Clists, wait a bit. */
1591 ttstart(tp);
1592 if (error = ttysleep(tp,
1593 &lbolt, TTOPRI | PCATCH, ttybuf, 0))
1594 break;
1595 goto loop;
1596 #else
1597 /* out of space */
1598 goto overfull;
1599 #endif
1600 }
1601 if (ISSET(tp->t_lflag, FLUSHO) ||
1602 tp->t_outq.c_cc > hiwat)
1603 break;
1604 }
1605 ttstart(tp);
1606 }
1607 out:
1608 /*
1609 * If cc is nonzero, we leave the uio structure inconsistent, as the
1610 * offset and iov pointers have moved forward, but it doesn't matter
1611 * (the call will either return short or restart with a new uio).
1612 */
1613 uio->uio_resid += cc;
1614 return (error);
1615
1616 #ifndef REAL_CLISTS
1617 overfull:
1618 /*
1619 * Since we are using ring buffers, if we can't insert any more into
1620 * the output queue, we can assume the ring is full and that someone
1621 * forgot to set the high water mark correctly. We set it and then
1622 * proceed as normal.
1623 */
1624 hiwat = tp->t_outq.c_cc - 1;
1625 #endif
1626
1627 ovhiwat:
1628 ttstart(tp);
1629 s = spltty();
1630 /*
1631 * This can only occur if FLUSHO is set in t_lflag,
1632 * or if ttstart/oproc is synchronous (or very fast).
1633 */
1634 if (tp->t_outq.c_cc <= hiwat) {
1635 splx(s);
1636 goto loop;
1637 }
1638 if (flag & IO_NDELAY) {
1639 splx(s);
1640 uio->uio_resid += cc;
1641 return (uio->uio_resid == cnt ? EWOULDBLOCK : 0);
1642 }
1643 SET(tp->t_state, TS_ASLEEP);
1644 error = ttysleep(tp, &tp->t_outq, TTOPRI | PCATCH, ttyout, 0);
1645 splx(s);
1646 if (error)
1647 goto out;
1648 goto loop;
1649 }
1650
1651 /*
1652 * Rubout one character from the rawq of tp
1653 * as cleanly as possible.
1654 */
1655 void
1656 ttyrub(c, tp)
1657 int c;
1658 register struct tty *tp;
1659 {
1660 register u_char *cp;
1661 register int savecol;
1662 int tabc, s;
1663
1664 if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC))
1665 return;
1666 CLR(tp->t_lflag, FLUSHO);
1667 if (ISSET(tp->t_lflag, ECHOE)) {
1668 if (tp->t_rocount == 0) {
1669 /*
1670 * Screwed by ttwrite; retype
1671 */
1672 ttyretype(tp);
1673 return;
1674 }
1675 if (c == ('\t' | TTY_QUOTE) || c == ('\n' | TTY_QUOTE))
1676 ttyrubo(tp, 2);
1677 else {
1678 CLR(c, ~TTY_CHARMASK);
1679 switch (CCLASS(c)) {
1680 case ORDINARY:
1681 ttyrubo(tp, 1);
1682 break;
1683 case BACKSPACE:
1684 case CONTROL:
1685 case NEWLINE:
1686 case RETURN:
1687 case VTAB:
1688 if (ISSET(tp->t_lflag, ECHOCTL))
1689 ttyrubo(tp, 2);
1690 break;
1691 case TAB:
1692 if (tp->t_rocount < tp->t_rawq.c_cc) {
1693 ttyretype(tp);
1694 return;
1695 }
1696 s = spltty();
1697 savecol = tp->t_column;
1698 SET(tp->t_state, TS_CNTTB);
1699 SET(tp->t_lflag, FLUSHO);
1700 tp->t_column = tp->t_rocol;
1701 for (cp = firstc(&tp->t_rawq, &tabc); cp;
1702 cp = nextc(&tp->t_rawq, cp, &tabc))
1703 ttyecho(tabc, tp);
1704 CLR(tp->t_lflag, FLUSHO);
1705 CLR(tp->t_state, TS_CNTTB);
1706 splx(s);
1707
1708 /* savecol will now be length of the tab. */
1709 savecol -= tp->t_column;
1710 tp->t_column += savecol;
1711 if (savecol > 8)
1712 savecol = 8; /* overflow screw */
1713 while (--savecol >= 0)
1714 (void)ttyoutput('\b', tp);
1715 break;
1716 default: /* XXX */
1717 #define PANICSTR "ttyrub: would panic c = %d, val = %d\n"
1718 (void)printf(PANICSTR, c, CCLASS(c));
1719 #ifdef notdef
1720 panic(PANICSTR, c, CCLASS(c));
1721 #endif
1722 }
1723 }
1724 } else if (ISSET(tp->t_lflag, ECHOPRT)) {
1725 if (!ISSET(tp->t_state, TS_ERASE)) {
1726 SET(tp->t_state, TS_ERASE);
1727 (void)ttyoutput('\\', tp);
1728 }
1729 ttyecho(c, tp);
1730 } else
1731 ttyecho(tp->t_cc[VERASE], tp);
1732 --tp->t_rocount;
1733 }
1734
1735 /*
1736 * Back over cnt characters, erasing them.
1737 */
1738 static void
1739 ttyrubo(tp, cnt)
1740 register struct tty *tp;
1741 int cnt;
1742 {
1743
1744 while (cnt-- > 0) {
1745 (void)ttyoutput('\b', tp);
1746 (void)ttyoutput(' ', tp);
1747 (void)ttyoutput('\b', tp);
1748 }
1749 }
1750
1751 /*
1752 * ttyretype --
1753 * Reprint the rawq line. Note, it is assumed that c_cc has already
1754 * been checked.
1755 */
1756 void
1757 ttyretype(tp)
1758 register struct tty *tp;
1759 {
1760 register u_char *cp;
1761 int s, c;
1762
1763 /* Echo the reprint character. */
1764 if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE)
1765 ttyecho(tp->t_cc[VREPRINT], tp);
1766
1767 (void)ttyoutput('\n', tp);
1768
1769 s = spltty();
1770 for (cp = firstc(&tp->t_canq, &c); cp; cp = nextc(&tp->t_canq, cp, &c))
1771 ttyecho(c, tp);
1772 for (cp = firstc(&tp->t_rawq, &c); cp; cp = nextc(&tp->t_rawq, cp, &c))
1773 ttyecho(c, tp);
1774 CLR(tp->t_state, TS_ERASE);
1775 splx(s);
1776
1777 tp->t_rocount = tp->t_rawq.c_cc;
1778 tp->t_rocol = 0;
1779 }
1780
1781 /*
1782 * Echo a typed character to the terminal.
1783 */
1784 static void
1785 ttyecho(c, tp)
1786 register int c;
1787 register struct tty *tp;
1788 {
1789
1790 if (!ISSET(tp->t_state, TS_CNTTB))
1791 CLR(tp->t_lflag, FLUSHO);
1792 if ((!ISSET(tp->t_lflag, ECHO) &&
1793 (!ISSET(tp->t_lflag, ECHONL) || c != '\n')) ||
1794 ISSET(tp->t_lflag, EXTPROC))
1795 return;
1796 if (((ISSET(tp->t_lflag, ECHOCTL) &&
1797 (ISSET(c, TTY_CHARMASK) <= 037 && c != '\t' && c != '\n')) ||
1798 ISSET(c, TTY_CHARMASK) == 0177)) {
1799 (void)ttyoutput('^', tp);
1800 CLR(c, ~TTY_CHARMASK);
1801 if (c == 0177)
1802 c = '?';
1803 else
1804 c += 'A' - 1;
1805 }
1806 (void)ttyoutput(c, tp);
1807 }
1808
1809 /*
1810 * Wake up any readers on a tty.
1811 */
1812 void
1813 ttwakeup(tp)
1814 register struct tty *tp;
1815 {
1816
1817 selwakeup(&tp->t_rsel);
1818 if (ISSET(tp->t_state, TS_ASYNC))
1819 pgsignal(tp->t_pgrp, SIGIO, 1);
1820 wakeup((caddr_t)&tp->t_rawq);
1821 }
1822
1823 /*
1824 * Look up a code for a specified speed in a conversion table;
1825 * used by drivers to map software speed values to hardware parameters.
1826 */
1827 int
1828 ttspeedtab(speed, table)
1829 int speed;
1830 register struct speedtab *table;
1831 {
1832
1833 for ( ; table->sp_speed != -1; table++)
1834 if (table->sp_speed == speed)
1835 return (table->sp_code);
1836 return (-1);
1837 }
1838
1839 /*
1840 * Set tty hi and low water marks.
1841 *
1842 * Try to arrange the dynamics so there's about one second
1843 * from hi to low water.
1844 */
1845 void
1846 ttsetwater(tp)
1847 struct tty *tp;
1848 {
1849 register int cps, x;
1850
1851 #define CLAMP(x, h, l) ((x) > h ? h : ((x) < l) ? l : (x))
1852
1853 cps = tp->t_ospeed / 10;
1854 tp->t_lowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT);
1855 x += cps;
1856 x = CLAMP(x, TTMAXHIWAT, TTMINHIWAT);
1857 tp->t_hiwat = roundup(x, CBSIZE);
1858 #undef CLAMP
1859 }
1860
1861 /*
1862 * Report on state of foreground process group.
1863 */
1864 void
1865 ttyinfo(tp)
1866 register struct tty *tp;
1867 {
1868 register struct proc *p, *pick;
1869 struct timeval utime, stime;
1870 int tmp;
1871
1872 if (ttycheckoutq(tp,0) == 0)
1873 return;
1874
1875 /* Print load average. */
1876 tmp = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT;
1877 ttyprintf(tp, "load: %d.%02d ", tmp / 100, tmp % 100);
1878
1879 if (tp->t_session == NULL)
1880 ttyprintf(tp, "not a controlling terminal\n");
1881 else if (tp->t_pgrp == NULL)
1882 ttyprintf(tp, "no foreground process group\n");
1883 else if ((p = tp->t_pgrp->pg_members.lh_first) == 0)
1884 ttyprintf(tp, "empty foreground process group\n");
1885 else {
1886 /* Pick interesting process. */
1887 for (pick = NULL; p != 0; p = p->p_pglist.le_next)
1888 if (proc_compare(pick, p))
1889 pick = p;
1890
1891 ttyprintf(tp, " cmd: %s %d [%s] ", pick->p_comm, pick->p_pid,
1892 pick->p_stat == SRUN ? "running" :
1893 pick->p_wmesg ? pick->p_wmesg : "iowait");
1894
1895 calcru(pick, &utime, &stime, NULL);
1896
1897 /* Round up and print user time. */
1898 utime.tv_usec += 5000;
1899 if (utime.tv_usec >= 1000000) {
1900 utime.tv_sec += 1;
1901 utime.tv_usec -= 1000000;
1902 }
1903 ttyprintf(tp, "%ld.%02ldu ", utime.tv_sec,
1904 utime.tv_usec / 10000);
1905
1906 /* Round up and print system time. */
1907 stime.tv_usec += 5000;
1908 if (stime.tv_usec >= 1000000) {
1909 stime.tv_sec += 1;
1910 stime.tv_usec -= 1000000;
1911 }
1912 ttyprintf(tp, "%ld.%02lds ", stime.tv_sec,
1913 stime.tv_usec / 10000);
1914
1915 #define pgtok(a) (((u_long) ((a) * NBPG) / 1024))
1916 /* Print percentage cpu, resident set size. */
1917 tmp = (pick->p_pctcpu * 10000 + FSCALE / 2) >> FSHIFT;
1918 ttyprintf(tp, "%d%% %ldk\n",
1919 tmp / 100,
1920 pick->p_stat == SIDL || pick->p_stat == SZOMB ? 0 :
1921 #ifdef pmap_resident_count
1922 pgtok(pmap_resident_count(&pick->p_vmspace->vm_pmap))
1923 #else
1924 pgtok(pick->p_vmspace->vm_rssize)
1925 #endif
1926 );
1927 }
1928 tp->t_rocount = 0; /* so pending input will be retyped if BS */
1929 }
1930
1931 /*
1932 * Returns 1 if p2 is "better" than p1
1933 *
1934 * The algorithm for picking the "interesting" process is thus:
1935 *
1936 * 1) Only foreground processes are eligible - implied.
1937 * 2) Runnable processes are favored over anything else. The runner
1938 * with the highest cpu utilization is picked (p_estcpu). Ties are
1939 * broken by picking the highest pid.
1940 * 3) The sleeper with the shortest sleep time is next. With ties,
1941 * we pick out just "short-term" sleepers (P_SINTR == 0).
1942 * 4) Further ties are broken by picking the highest pid.
1943 */
1944 #define ISRUN(p) (((p)->p_stat == SRUN) || ((p)->p_stat == SIDL))
1945 #define TESTAB(a, b) ((a)<<1 | (b))
1946 #define ONLYA 2
1947 #define ONLYB 1
1948 #define BOTH 3
1949
1950 static int
1951 proc_compare(p1, p2)
1952 register struct proc *p1, *p2;
1953 {
1954
1955 if (p1 == NULL)
1956 return (1);
1957 /*
1958 * see if at least one of them is runnable
1959 */
1960 switch (TESTAB(ISRUN(p1), ISRUN(p2))) {
1961 case ONLYA:
1962 return (0);
1963 case ONLYB:
1964 return (1);
1965 case BOTH:
1966 /*
1967 * tie - favor one with highest recent cpu utilization
1968 */
1969 if (p2->p_estcpu > p1->p_estcpu)
1970 return (1);
1971 if (p1->p_estcpu > p2->p_estcpu)
1972 return (0);
1973 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
1974 }
1975 /*
1976 * weed out zombies
1977 */
1978 switch (TESTAB(p1->p_stat == SZOMB, p2->p_stat == SZOMB)) {
1979 case ONLYA:
1980 return (1);
1981 case ONLYB:
1982 return (0);
1983 case BOTH:
1984 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
1985 }
1986 /*
1987 * pick the one with the smallest sleep time
1988 */
1989 if (p2->p_slptime > p1->p_slptime)
1990 return (0);
1991 if (p1->p_slptime > p2->p_slptime)
1992 return (1);
1993 /*
1994 * favor one sleeping in a non-interruptible sleep
1995 */
1996 if (p1->p_flag & P_SINTR && (p2->p_flag & P_SINTR) == 0)
1997 return (1);
1998 if (p2->p_flag & P_SINTR && (p1->p_flag & P_SINTR) == 0)
1999 return (0);
2000 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
2001 }
2002
2003 /*
2004 * Output char to tty; console putchar style.
2005 */
2006 int
2007 tputchar(c, tp)
2008 int c;
2009 struct tty *tp;
2010 {
2011 register int s;
2012
2013 s = spltty();
2014 if (ISSET(tp->t_state,
2015 TS_CARR_ON | TS_ISOPEN) != (TS_CARR_ON | TS_ISOPEN)) {
2016 splx(s);
2017 return (-1);
2018 }
2019 if (c == '\n')
2020 (void)ttyoutput('\r', tp);
2021 (void)ttyoutput(c, tp);
2022 ttstart(tp);
2023 splx(s);
2024 return (0);
2025 }
2026
2027 /*
2028 * Sleep on chan, returning ERESTART if tty changed while we napped and
2029 * returning any errors (e.g. EINTR/ETIMEDOUT) reported by tsleep. If
2030 * the tty is revoked, restarting a pending call will redo validation done
2031 * at the start of the call.
2032 */
2033 int
2034 ttysleep(tp, chan, pri, wmesg, timo)
2035 struct tty *tp;
2036 void *chan;
2037 int pri, timo;
2038 char *wmesg;
2039 {
2040 int error;
2041 short gen;
2042
2043 gen = tp->t_gen;
2044 if ((error = tsleep(chan, pri, wmesg, timo)) != 0)
2045 return (error);
2046 return (tp->t_gen == gen ? 0 : ERESTART);
2047 }
2048
2049 /*
2050 * Initialise the global tty list.
2051 */
2052 void
2053 tty_init()
2054 {
2055
2056 TAILQ_INIT(&ttylist);
2057 tty_count = 0;
2058 }
2059
2060 /*
2061 * Attach a tty to the tty list.
2062 *
2063 * This should be called ONLY once per real tty (including pty's).
2064 * eg, on the sparc, the keyboard and mouse have struct tty's that are
2065 * distinctly NOT usable as tty's, and thus should not be attached to
2066 * the ttylist. This is why this call is not done from ttymalloc().
2067 *
2068 * Device drivers should attach tty's at a similar time that they are
2069 * ttymalloc()'ed, or, for the case of statically allocated struct tty's
2070 * either in the attach or (first) open routine.
2071 */
2072 void
2073 tty_attach(tp)
2074 struct tty *tp;
2075 {
2076
2077 TAILQ_INSERT_TAIL(&ttylist, tp, tty_link);
2078 ++tty_count;
2079 }
2080
2081 /*
2082 * Remove a tty from the tty list.
2083 */
2084 void
2085 tty_detach(tp)
2086 struct tty *tp;
2087 {
2088
2089 --tty_count;
2090 #ifdef DIAGNOSTIC
2091 if (tty_count < 0)
2092 panic("tty_detach: tty_count < 0");
2093 #endif
2094 TAILQ_REMOVE(&ttylist, tp, tty_link);
2095 }
2096
2097 /*
2098 * Allocate a tty structure and its associated buffers.
2099 */
2100 struct tty *
2101 ttymalloc()
2102 {
2103 struct tty *tp;
2104
2105 MALLOC(tp, struct tty *, sizeof(struct tty), M_TTYS, M_WAITOK);
2106 bzero(tp, sizeof *tp);
2107 /* XXX: default to 1024 chars for now */
2108 clalloc(&tp->t_rawq, 1024, 1);
2109 clalloc(&tp->t_canq, 1024, 1);
2110 /* output queue doesn't need quoting */
2111 clalloc(&tp->t_outq, 1024, 0);
2112 return(tp);
2113 }
2114
2115 /*
2116 * Free a tty structure and its buffers.
2117 *
2118 * Be sure to call tty_detach() for any tty that has been
2119 * tty_attach()ed.
2120 */
2121 void
2122 ttyfree(tp)
2123 struct tty *tp;
2124 {
2125
2126 clfree(&tp->t_rawq);
2127 clfree(&tp->t_canq);
2128 clfree(&tp->t_outq);
2129 FREE(tp, M_TTYS);
2130 }
2131