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