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