FreeBSD/Linux Kernel Cross Reference
sys/kern/tty.c
1 /*-
2 * Copyright (c) 1982, 1986, 1990, 1991, 1993
3 * The Regents of the University of California. All rights reserved.
4 * (c) UNIX System Laboratories, Inc.
5 * All or some portions of this file are derived from material licensed
6 * to the University of California by American Telephone and Telegraph
7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8 * the permission of UNIX System Laboratories, Inc.
9 *
10 * Copyright (c) 2002 Networks Associates Technologies, Inc.
11 * All rights reserved.
12 *
13 * Portions of this software were developed for the FreeBSD Project by
14 * ThinkSec AS and NAI Labs, the Security Research Division of Network
15 * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035
16 * ("CBOSS"), as part of the DARPA CHATS research program.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
20 * are met:
21 * 1. Redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer.
23 * 2. Redistributions in binary form must reproduce the above copyright
24 * notice, this list of conditions and the following disclaimer in the
25 * documentation and/or other materials provided with the distribution.
26 * 3. All advertising materials mentioning features or use of this software
27 * must display the following acknowledgement:
28 * This product includes software developed by the University of
29 * California, Berkeley and its contributors.
30 * 4. Neither the name of the University nor the names of its contributors
31 * may be used to endorse or promote products derived from this software
32 * without specific prior written permission.
33 *
34 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
35 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
38 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
44 * SUCH DAMAGE.
45 *
46 * @(#)tty.c 8.8 (Berkeley) 1/21/94
47 * $FreeBSD: releng/5.1/sys/kern/tty.c 114985 2003-05-14 00:03:55Z ps $
48 */
49
50 /*-
51 * TODO:
52 * o Fix races for sending the start char in ttyflush().
53 * o Handle inter-byte timeout for "MIN > 0, TIME > 0" in ttyselect().
54 * With luck, there will be MIN chars before select() returns().
55 * o Handle CLOCAL consistently for ptys. Perhaps disallow setting it.
56 * o Don't allow input in TS_ZOMBIE case. It would be visible through
57 * FIONREAD.
58 * o Do the new sio locking stuff here and use it to avoid special
59 * case for EXTPROC?
60 * o Lock PENDIN too?
61 * o Move EXTPROC and/or PENDIN to t_state?
62 * o Wrap most of ttioctl in spltty/splx.
63 * o Implement TIOCNOTTY or remove it from <sys/ioctl.h>.
64 * o Send STOP if IXOFF is toggled off while TS_TBLOCK is set.
65 * o Don't allow certain termios flags to affect disciplines other
66 * than TTYDISC. Cancel their effects before switch disciplines
67 * and ignore them if they are set while we are in another
68 * discipline.
69 * o Now that historical speed conversions are handled here, don't
70 * do them in drivers.
71 * o Check for TS_CARR_ON being set while everything is closed and not
72 * waiting for carrier. TS_CARR_ON isn't cleared if nothing is open,
73 * so it would live until the next open even if carrier drops.
74 * o Restore TS_WOPEN since it is useful in pstat. It must be cleared
75 * only when _all_ openers leave open().
76 */
77
78 #include "opt_compat.h"
79 #include "opt_tty.h"
80
81 #include <sys/param.h>
82 #include <sys/systm.h>
83 #include <sys/filio.h>
84 #include <sys/lock.h>
85 #include <sys/mutex.h>
86 #include <sys/namei.h>
87 #include <sys/sx.h>
88 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
89 #include <sys/ioctl_compat.h>
90 #endif
91 #include <sys/proc.h>
92 #define TTYDEFCHARS
93 #include <sys/tty.h>
94 #undef TTYDEFCHARS
95 #include <sys/fcntl.h>
96 #include <sys/conf.h>
97 #include <sys/poll.h>
98 #include <sys/kernel.h>
99 #include <sys/vnode.h>
100 #include <sys/signalvar.h>
101 #include <sys/resourcevar.h>
102 #include <sys/malloc.h>
103 #include <sys/filedesc.h>
104 #include <sys/sysctl.h>
105
106 #include <vm/vm.h>
107 #include <vm/pmap.h>
108 #include <vm/vm_map.h>
109
110 MALLOC_DEFINE(M_TTYS, "ttys", "tty data structures");
111
112 long tk_cancc;
113 long tk_nin;
114 long tk_nout;
115 long tk_rawcc;
116
117 static int proc_compare(struct proc *p1, struct proc *p2);
118 static int ttnread(struct tty *tp);
119 static void ttyecho(int c, struct tty *tp);
120 static int ttyoutput(int c, struct tty *tp);
121 static void ttypend(struct tty *tp);
122 static void ttyretype(struct tty *tp);
123 static void ttyrub(int c, struct tty *tp);
124 static void ttyrubo(struct tty *tp, int cnt);
125 static void ttyunblock(struct tty *tp);
126 static int ttywflush(struct tty *tp);
127 static int filt_ttyread(struct knote *kn, long hint);
128 static void filt_ttyrdetach(struct knote *kn);
129 static int filt_ttywrite(struct knote *kn, long hint);
130 static void filt_ttywdetach(struct knote *kn);
131
132 /*
133 * Table with character classes and parity. The 8th bit indicates parity,
134 * the 7th bit indicates the character is an alphameric or underscore (for
135 * ALTWERASE), and the low 6 bits indicate delay type. If the low 6 bits
136 * are 0 then the character needs no special processing on output; classes
137 * other than 0 might be translated or (not currently) require delays.
138 */
139 #define E 0x00 /* Even parity. */
140 #define O 0x80 /* Odd parity. */
141 #define PARITY(c) (char_type[c] & O)
142
143 #define ALPHA 0x40 /* Alpha or underscore. */
144 #define ISALPHA(c) (char_type[(c) & TTY_CHARMASK] & ALPHA)
145
146 #define CCLASSMASK 0x3f
147 #define CCLASS(c) (char_type[c] & CCLASSMASK)
148
149 #define BS BACKSPACE
150 #define CC CONTROL
151 #define CR RETURN
152 #define NA ORDINARY | ALPHA
153 #define NL NEWLINE
154 #define NO ORDINARY
155 #define TB TAB
156 #define VT VTAB
157
158 static u_char const char_type[] = {
159 E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC, /* nul - bel */
160 O|BS, E|TB, E|NL, O|CC, E|VT, O|CR, O|CC, E|CC, /* bs - si */
161 O|CC, E|CC, E|CC, O|CC, E|CC, O|CC, O|CC, E|CC, /* dle - etb */
162 E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC, /* can - us */
163 O|NO, E|NO, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* sp - ' */
164 E|NO, O|NO, O|NO, E|NO, O|NO, E|NO, E|NO, O|NO, /* ( - / */
165 E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* 0 - 7 */
166 O|NA, E|NA, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* 8 - ? */
167 O|NO, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* @ - G */
168 E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* H - O */
169 E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* P - W */
170 O|NA, E|NA, E|NA, O|NO, E|NO, O|NO, O|NO, O|NA, /* X - _ */
171 E|NO, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* ` - g */
172 O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* h - o */
173 O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* p - w */
174 E|NA, O|NA, O|NA, E|NO, O|NO, E|NO, E|NO, O|CC, /* x - del */
175 /*
176 * Meta chars; should be settable per character set;
177 * for now, treat them all as normal characters.
178 */
179 NA, NA, NA, NA, NA, NA, NA, NA,
180 NA, NA, NA, NA, NA, NA, NA, NA,
181 NA, NA, NA, NA, NA, NA, NA, NA,
182 NA, NA, NA, NA, NA, NA, NA, NA,
183 NA, NA, NA, NA, NA, NA, NA, NA,
184 NA, NA, NA, NA, NA, NA, NA, NA,
185 NA, NA, NA, NA, NA, NA, NA, NA,
186 NA, NA, NA, NA, NA, NA, NA, NA,
187 NA, NA, NA, NA, NA, NA, NA, NA,
188 NA, NA, NA, NA, NA, NA, NA, NA,
189 NA, NA, NA, NA, NA, NA, NA, NA,
190 NA, NA, NA, NA, NA, NA, NA, NA,
191 NA, NA, NA, NA, NA, NA, NA, NA,
192 NA, NA, NA, NA, NA, NA, NA, NA,
193 NA, NA, NA, NA, NA, NA, NA, NA,
194 NA, NA, NA, NA, NA, NA, NA, NA,
195 };
196 #undef BS
197 #undef CC
198 #undef CR
199 #undef NA
200 #undef NL
201 #undef NO
202 #undef TB
203 #undef VT
204
205 /* Macros to clear/set/test flags. */
206 #define SET(t, f) (t) |= (f)
207 #define CLR(t, f) (t) &= ~(f)
208 #define ISSET(t, f) ((t) & (f))
209
210 #undef MAX_INPUT /* XXX wrong in <sys/syslimits.h> */
211 #define MAX_INPUT TTYHOG /* XXX limit is usually larger for !ICANON */
212
213 /*
214 * list of struct tty where pstat(8) can pick it up with sysctl
215 */
216 static SLIST_HEAD(, tty) tty_list;
217
218 static int drainwait = 5*60;
219 SYSCTL_INT(_kern, OID_AUTO, drainwait, CTLFLAG_RW, &drainwait,
220 0, "Output drain timeout in seconds");
221
222 /*
223 * Initial open of tty, or (re)entry to standard tty line discipline.
224 */
225 int
226 ttyopen(dev_t device, struct tty *tp)
227 {
228 int s;
229
230 s = spltty();
231 tp->t_dev = device;
232 if (!ISSET(tp->t_state, TS_ISOPEN)) {
233 SET(tp->t_state, TS_ISOPEN);
234 if (ISSET(tp->t_cflag, CLOCAL))
235 SET(tp->t_state, TS_CONNECTED);
236 bzero(&tp->t_winsize, sizeof(tp->t_winsize));
237 }
238 /* XXX don't hang forever on output */
239 if (tp->t_timeout < 0)
240 tp->t_timeout = drainwait*hz;
241 ttsetwater(tp);
242 splx(s);
243 return (0);
244 }
245
246 /*
247 * Handle close() on a tty line: flush and set to initial state,
248 * bumping generation number so that pending read/write calls
249 * can detect recycling of the tty.
250 * XXX our caller should have done `spltty(); l_close(); ttyclose();'
251 * and l_close() should have flushed, but we repeat the spltty() and
252 * the flush in case there are buggy callers.
253 */
254 int
255 ttyclose(struct tty *tp)
256 {
257 int s;
258
259 funsetown(&tp->t_sigio);
260 s = spltty();
261 if (constty == tp)
262 constty = NULL;
263
264 ttyflush(tp, FREAD | FWRITE);
265 clist_free_cblocks(&tp->t_canq);
266 clist_free_cblocks(&tp->t_outq);
267 clist_free_cblocks(&tp->t_rawq);
268
269 tp->t_gen++;
270 tp->t_line = TTYDISC;
271 tp->t_pgrp = NULL;
272 tp->t_session = NULL;
273 tp->t_state = 0;
274 splx(s);
275 return (0);
276 }
277
278 #define FLUSHQ(q) { \
279 if ((q)->c_cc) \
280 ndflush(q, (q)->c_cc); \
281 }
282
283 /* Is 'c' a line delimiter ("break" character)? */
284 #define TTBREAKC(c, lflag) \
285 ((c) == '\n' || (((c) == cc[VEOF] || \
286 (c) == cc[VEOL] || ((c) == cc[VEOL2] && lflag & IEXTEN)) && \
287 (c) != _POSIX_VDISABLE))
288
289 /*
290 * Process input of a single character received on a tty.
291 */
292 int
293 ttyinput(int c, struct tty *tp)
294 {
295 tcflag_t iflag, lflag;
296 cc_t *cc;
297 int i, err;
298
299 /*
300 * If input is pending take it first.
301 */
302 lflag = tp->t_lflag;
303 if (ISSET(lflag, PENDIN))
304 ttypend(tp);
305 /*
306 * Gather stats.
307 */
308 if (ISSET(lflag, ICANON)) {
309 ++tk_cancc;
310 ++tp->t_cancc;
311 } else {
312 ++tk_rawcc;
313 ++tp->t_rawcc;
314 }
315 ++tk_nin;
316
317 /*
318 * Block further input iff:
319 * current input > threshold AND input is available to user program
320 * AND input flow control is enabled and not yet invoked.
321 * The 3 is slop for PARMRK.
322 */
323 iflag = tp->t_iflag;
324 if (tp->t_rawq.c_cc + tp->t_canq.c_cc > tp->t_ihiwat - 3 &&
325 (!ISSET(lflag, ICANON) || tp->t_canq.c_cc != 0) &&
326 (ISSET(tp->t_cflag, CRTS_IFLOW) || ISSET(iflag, IXOFF)) &&
327 !ISSET(tp->t_state, TS_TBLOCK))
328 ttyblock(tp);
329
330 /* Handle exceptional conditions (break, parity, framing). */
331 cc = tp->t_cc;
332 err = (ISSET(c, TTY_ERRORMASK));
333 if (err) {
334 CLR(c, TTY_ERRORMASK);
335 if (ISSET(err, TTY_BI)) {
336 if (ISSET(iflag, IGNBRK))
337 return (0);
338 if (ISSET(iflag, BRKINT)) {
339 ttyflush(tp, FREAD | FWRITE);
340 if (tp->t_pgrp != NULL) {
341 PGRP_LOCK(tp->t_pgrp);
342 pgsignal(tp->t_pgrp, SIGINT, 1);
343 PGRP_UNLOCK(tp->t_pgrp);
344 }
345 goto endcase;
346 }
347 if (ISSET(iflag, PARMRK))
348 goto parmrk;
349 } else if ((ISSET(err, TTY_PE) && ISSET(iflag, INPCK))
350 || ISSET(err, TTY_FE)) {
351 if (ISSET(iflag, IGNPAR))
352 return (0);
353 else if (ISSET(iflag, PARMRK)) {
354 parmrk:
355 if (tp->t_rawq.c_cc + tp->t_canq.c_cc >
356 MAX_INPUT - 3)
357 goto input_overflow;
358 (void)putc(0377 | TTY_QUOTE, &tp->t_rawq);
359 (void)putc(0 | TTY_QUOTE, &tp->t_rawq);
360 (void)putc(c | TTY_QUOTE, &tp->t_rawq);
361 goto endcase;
362 } else
363 c = 0;
364 }
365 }
366
367 if (!ISSET(tp->t_state, TS_TYPEN) && ISSET(iflag, ISTRIP))
368 CLR(c, 0x80);
369 if (!ISSET(lflag, EXTPROC)) {
370 /*
371 * Check for literal nexting very first
372 */
373 if (ISSET(tp->t_state, TS_LNCH)) {
374 SET(c, TTY_QUOTE);
375 CLR(tp->t_state, TS_LNCH);
376 }
377 /*
378 * Scan for special characters. This code
379 * is really just a big case statement with
380 * non-constant cases. The bottom of the
381 * case statement is labeled ``endcase'', so goto
382 * it after a case match, or similar.
383 */
384
385 /*
386 * Control chars which aren't controlled
387 * by ICANON, ISIG, or IXON.
388 */
389 if (ISSET(lflag, IEXTEN)) {
390 if (CCEQ(cc[VLNEXT], c)) {
391 if (ISSET(lflag, ECHO)) {
392 if (ISSET(lflag, ECHOE)) {
393 (void)ttyoutput('^', tp);
394 (void)ttyoutput('\b', tp);
395 } else
396 ttyecho(c, tp);
397 }
398 SET(tp->t_state, TS_LNCH);
399 goto endcase;
400 }
401 if (CCEQ(cc[VDISCARD], c)) {
402 if (ISSET(lflag, FLUSHO))
403 CLR(tp->t_lflag, FLUSHO);
404 else {
405 ttyflush(tp, FWRITE);
406 ttyecho(c, tp);
407 if (tp->t_rawq.c_cc + tp->t_canq.c_cc)
408 ttyretype(tp);
409 SET(tp->t_lflag, FLUSHO);
410 }
411 goto startoutput;
412 }
413 }
414 /*
415 * Signals.
416 */
417 if (ISSET(lflag, ISIG)) {
418 if (CCEQ(cc[VINTR], c) || CCEQ(cc[VQUIT], c)) {
419 if (!ISSET(lflag, NOFLSH))
420 ttyflush(tp, FREAD | FWRITE);
421 ttyecho(c, tp);
422 if (tp->t_pgrp != NULL) {
423 PGRP_LOCK(tp->t_pgrp);
424 pgsignal(tp->t_pgrp,
425 CCEQ(cc[VINTR], c) ? SIGINT : SIGQUIT, 1);
426 PGRP_UNLOCK(tp->t_pgrp);
427 }
428 goto endcase;
429 }
430 if (CCEQ(cc[VSUSP], c)) {
431 if (!ISSET(lflag, NOFLSH))
432 ttyflush(tp, FREAD);
433 ttyecho(c, tp);
434 if (tp->t_pgrp != NULL) {
435 PGRP_LOCK(tp->t_pgrp);
436 pgsignal(tp->t_pgrp, SIGTSTP, 1);
437 PGRP_UNLOCK(tp->t_pgrp);
438 }
439 goto endcase;
440 }
441 }
442 /*
443 * Handle start/stop characters.
444 */
445 if (ISSET(iflag, IXON)) {
446 if (CCEQ(cc[VSTOP], c)) {
447 if (!ISSET(tp->t_state, TS_TTSTOP)) {
448 SET(tp->t_state, TS_TTSTOP);
449 (*tp->t_stop)(tp, 0);
450 return (0);
451 }
452 if (!CCEQ(cc[VSTART], c))
453 return (0);
454 /*
455 * if VSTART == VSTOP then toggle
456 */
457 goto endcase;
458 }
459 if (CCEQ(cc[VSTART], c))
460 goto restartoutput;
461 }
462 /*
463 * IGNCR, ICRNL, & INLCR
464 */
465 if (c == '\r') {
466 if (ISSET(iflag, IGNCR))
467 return (0);
468 else if (ISSET(iflag, ICRNL))
469 c = '\n';
470 } else if (c == '\n' && ISSET(iflag, INLCR))
471 c = '\r';
472 }
473 if (!ISSET(tp->t_lflag, EXTPROC) && ISSET(lflag, ICANON)) {
474 /*
475 * From here on down canonical mode character
476 * processing takes place.
477 */
478 /*
479 * erase or erase2 (^H / ^?)
480 */
481 if (CCEQ(cc[VERASE], c) || CCEQ(cc[VERASE2], c) ) {
482 if (tp->t_rawq.c_cc)
483 ttyrub(unputc(&tp->t_rawq), tp);
484 goto endcase;
485 }
486 /*
487 * kill (^U)
488 */
489 if (CCEQ(cc[VKILL], c)) {
490 if (ISSET(lflag, ECHOKE) &&
491 tp->t_rawq.c_cc == tp->t_rocount &&
492 !ISSET(lflag, ECHOPRT))
493 while (tp->t_rawq.c_cc)
494 ttyrub(unputc(&tp->t_rawq), tp);
495 else {
496 ttyecho(c, tp);
497 if (ISSET(lflag, ECHOK) ||
498 ISSET(lflag, ECHOKE))
499 ttyecho('\n', tp);
500 FLUSHQ(&tp->t_rawq);
501 tp->t_rocount = 0;
502 }
503 CLR(tp->t_state, TS_LOCAL);
504 goto endcase;
505 }
506 /*
507 * word erase (^W)
508 */
509 if (CCEQ(cc[VWERASE], c) && ISSET(lflag, IEXTEN)) {
510 int ctype;
511
512 /*
513 * erase whitespace
514 */
515 while ((c = unputc(&tp->t_rawq)) == ' ' || c == '\t')
516 ttyrub(c, tp);
517 if (c == -1)
518 goto endcase;
519 /*
520 * erase last char of word and remember the
521 * next chars type (for ALTWERASE)
522 */
523 ttyrub(c, tp);
524 c = unputc(&tp->t_rawq);
525 if (c == -1)
526 goto endcase;
527 if (c == ' ' || c == '\t') {
528 (void)putc(c, &tp->t_rawq);
529 goto endcase;
530 }
531 ctype = ISALPHA(c);
532 /*
533 * erase rest of word
534 */
535 do {
536 ttyrub(c, tp);
537 c = unputc(&tp->t_rawq);
538 if (c == -1)
539 goto endcase;
540 } while (c != ' ' && c != '\t' &&
541 (!ISSET(lflag, ALTWERASE) || ISALPHA(c) == ctype));
542 (void)putc(c, &tp->t_rawq);
543 goto endcase;
544 }
545 /*
546 * reprint line (^R)
547 */
548 if (CCEQ(cc[VREPRINT], c) && ISSET(lflag, IEXTEN)) {
549 ttyretype(tp);
550 goto endcase;
551 }
552 /*
553 * ^T - kernel info and generate SIGINFO
554 */
555 if (CCEQ(cc[VSTATUS], c) && ISSET(lflag, IEXTEN)) {
556 if (ISSET(lflag, ISIG) && tp->t_pgrp != NULL) {
557 PGRP_LOCK(tp->t_pgrp);
558 pgsignal(tp->t_pgrp, SIGINFO, 1);
559 PGRP_UNLOCK(tp->t_pgrp);
560 }
561 if (!ISSET(lflag, NOKERNINFO))
562 ttyinfo(tp);
563 goto endcase;
564 }
565 }
566 /*
567 * Check for input buffer overflow
568 */
569 if (tp->t_rawq.c_cc + tp->t_canq.c_cc >= MAX_INPUT) {
570 input_overflow:
571 if (ISSET(iflag, IMAXBEL)) {
572 if (tp->t_outq.c_cc < tp->t_ohiwat)
573 (void)ttyoutput(CTRL('g'), tp);
574 }
575 goto endcase;
576 }
577
578 if ( c == 0377 && ISSET(iflag, PARMRK) && !ISSET(iflag, ISTRIP)
579 && ISSET(iflag, IGNBRK|IGNPAR) != (IGNBRK|IGNPAR))
580 (void)putc(0377 | TTY_QUOTE, &tp->t_rawq);
581
582 /*
583 * Put data char in q for user and
584 * wakeup on seeing a line delimiter.
585 */
586 if (putc(c, &tp->t_rawq) >= 0) {
587 if (!ISSET(lflag, ICANON)) {
588 ttwakeup(tp);
589 ttyecho(c, tp);
590 goto endcase;
591 }
592 if (TTBREAKC(c, lflag)) {
593 tp->t_rocount = 0;
594 catq(&tp->t_rawq, &tp->t_canq);
595 ttwakeup(tp);
596 } else if (tp->t_rocount++ == 0)
597 tp->t_rocol = tp->t_column;
598 if (ISSET(tp->t_state, TS_ERASE)) {
599 /*
600 * end of prterase \.../
601 */
602 CLR(tp->t_state, TS_ERASE);
603 (void)ttyoutput('/', tp);
604 }
605 i = tp->t_column;
606 ttyecho(c, tp);
607 if (CCEQ(cc[VEOF], c) && ISSET(lflag, ECHO)) {
608 /*
609 * Place the cursor over the '^' of the ^D.
610 */
611 i = imin(2, tp->t_column - i);
612 while (i > 0) {
613 (void)ttyoutput('\b', tp);
614 i--;
615 }
616 }
617 }
618 endcase:
619 /*
620 * IXANY means allow any character to restart output.
621 */
622 if (ISSET(tp->t_state, TS_TTSTOP) &&
623 !ISSET(iflag, IXANY) && cc[VSTART] != cc[VSTOP])
624 return (0);
625 restartoutput:
626 CLR(tp->t_lflag, FLUSHO);
627 CLR(tp->t_state, TS_TTSTOP);
628 startoutput:
629 return (ttstart(tp));
630 }
631
632 /*
633 * Output a single character on a tty, doing output processing
634 * as needed (expanding tabs, newline processing, etc.).
635 * Returns < 0 if succeeds, otherwise returns char to resend.
636 * Must be recursive.
637 */
638 static int
639 ttyoutput(int c, struct tty *tp)
640 {
641 tcflag_t oflag;
642 int col, s;
643
644 oflag = tp->t_oflag;
645 if (!ISSET(oflag, OPOST)) {
646 if (ISSET(tp->t_lflag, FLUSHO))
647 return (-1);
648 if (putc(c, &tp->t_outq))
649 return (c);
650 tk_nout++;
651 tp->t_outcc++;
652 return (-1);
653 }
654 /*
655 * Do tab expansion if OXTABS is set. Special case if we external
656 * processing, we don't do the tab expansion because we'll probably
657 * get it wrong. If tab expansion needs to be done, let it happen
658 * externally.
659 */
660 CLR(c, ~TTY_CHARMASK);
661 if (c == '\t' &&
662 ISSET(oflag, OXTABS) && !ISSET(tp->t_lflag, EXTPROC)) {
663 c = 8 - (tp->t_column & 7);
664 if (!ISSET(tp->t_lflag, FLUSHO)) {
665 s = spltty(); /* Don't interrupt tabs. */
666 c -= b_to_q(" ", c, &tp->t_outq);
667 tk_nout += c;
668 tp->t_outcc += c;
669 splx(s);
670 }
671 tp->t_column += c;
672 return (c ? -1 : '\t');
673 }
674 if (c == CEOT && ISSET(oflag, ONOEOT))
675 return (-1);
676
677 /*
678 * Newline translation: if ONLCR is set,
679 * translate newline into "\r\n".
680 */
681 if (c == '\n' && ISSET(tp->t_oflag, ONLCR)) {
682 tk_nout++;
683 tp->t_outcc++;
684 if (!ISSET(tp->t_lflag, FLUSHO) && putc('\r', &tp->t_outq))
685 return (c);
686 }
687 /* If OCRNL is set, translate "\r" into "\n". */
688 else if (c == '\r' && ISSET(tp->t_oflag, OCRNL))
689 c = '\n';
690 /* If ONOCR is set, don't transmit CRs when on column 0. */
691 else if (c == '\r' && ISSET(tp->t_oflag, ONOCR) && tp->t_column == 0)
692 return (-1);
693
694 tk_nout++;
695 tp->t_outcc++;
696 if (!ISSET(tp->t_lflag, FLUSHO) && putc(c, &tp->t_outq))
697 return (c);
698
699 col = tp->t_column;
700 switch (CCLASS(c)) {
701 case BACKSPACE:
702 if (col > 0)
703 --col;
704 break;
705 case CONTROL:
706 break;
707 case NEWLINE:
708 if (ISSET(tp->t_oflag, ONLCR | ONLRET))
709 col = 0;
710 break;
711 case RETURN:
712 col = 0;
713 break;
714 case ORDINARY:
715 ++col;
716 break;
717 case TAB:
718 col = (col + 8) & ~7;
719 break;
720 }
721 tp->t_column = col;
722 return (-1);
723 }
724
725 /*
726 * Ioctls for all tty devices. Called after line-discipline specific ioctl
727 * has been called to do discipline-specific functions and/or reject any
728 * of these ioctl commands.
729 */
730 /* ARGSUSED */
731 int
732 ttioctl(struct tty *tp, u_long cmd, void *data, int flag)
733 {
734 struct proc *p;
735 struct thread *td;
736 struct pgrp *pgrp;
737 int s, error;
738
739 td = curthread; /* XXX */
740 p = td->td_proc;
741
742 /* If the ioctl involves modification, hang if in the background. */
743 switch (cmd) {
744 case TIOCCBRK:
745 case TIOCCONS:
746 case TIOCDRAIN:
747 case TIOCEXCL:
748 case TIOCFLUSH:
749 #ifdef TIOCHPCL
750 case TIOCHPCL:
751 #endif
752 case TIOCNXCL:
753 case TIOCSBRK:
754 case TIOCSCTTY:
755 case TIOCSDRAINWAIT:
756 case TIOCSETA:
757 case TIOCSETAF:
758 case TIOCSETAW:
759 case TIOCSETD:
760 case TIOCSPGRP:
761 case TIOCSTART:
762 case TIOCSTAT:
763 case TIOCSTI:
764 case TIOCSTOP:
765 case TIOCSWINSZ:
766 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
767 case TIOCLBIC:
768 case TIOCLBIS:
769 case TIOCLSET:
770 case TIOCSETC:
771 case OTIOCSETD:
772 case TIOCSETN:
773 case TIOCSETP:
774 case TIOCSLTC:
775 #endif
776 sx_slock(&proctree_lock);
777 PROC_LOCK(p);
778 while (isbackground(p, tp) && !(p->p_flag & P_PPWAIT) &&
779 !SIGISMEMBER(p->p_sigacts->ps_sigignore, SIGTTOU) &&
780 !SIGISMEMBER(td->td_sigmask, SIGTTOU)) {
781 pgrp = p->p_pgrp;
782 PROC_UNLOCK(p);
783 if (pgrp->pg_jobc == 0) {
784 sx_sunlock(&proctree_lock);
785 return (EIO);
786 }
787 PGRP_LOCK(pgrp);
788 sx_sunlock(&proctree_lock);
789 pgsignal(pgrp, SIGTTOU, 1);
790 PGRP_UNLOCK(pgrp);
791 error = ttysleep(tp, &lbolt, TTOPRI | PCATCH, "ttybg1",
792 0);
793 if (error)
794 return (error);
795 sx_slock(&proctree_lock);
796 PROC_LOCK(p);
797 }
798 PROC_UNLOCK(p);
799 sx_sunlock(&proctree_lock);
800 break;
801 }
802
803 switch (cmd) { /* Process the ioctl. */
804 case FIOASYNC: /* set/clear async i/o */
805 s = spltty();
806 if (*(int *)data)
807 SET(tp->t_state, TS_ASYNC);
808 else
809 CLR(tp->t_state, TS_ASYNC);
810 splx(s);
811 break;
812 case FIONBIO: /* set/clear non-blocking i/o */
813 break; /* XXX: delete. */
814 case FIONREAD: /* get # bytes to read */
815 s = spltty();
816 *(int *)data = ttnread(tp);
817 splx(s);
818 break;
819
820 case FIOSETOWN:
821 /*
822 * Policy -- Don't allow FIOSETOWN on someone else's
823 * controlling tty
824 */
825 if (tp->t_session != NULL && !isctty(p, tp))
826 return (ENOTTY);
827
828 error = fsetown(*(int *)data, &tp->t_sigio);
829 if (error)
830 return (error);
831 break;
832 case FIOGETOWN:
833 if (tp->t_session != NULL && !isctty(p, tp))
834 return (ENOTTY);
835 *(int *)data = fgetown(&tp->t_sigio);
836 break;
837
838 case TIOCEXCL: /* set exclusive use of tty */
839 s = spltty();
840 SET(tp->t_state, TS_XCLUDE);
841 splx(s);
842 break;
843 case TIOCFLUSH: { /* flush buffers */
844 int flags = *(int *)data;
845
846 if (flags == 0)
847 flags = FREAD | FWRITE;
848 else
849 flags &= FREAD | FWRITE;
850 ttyflush(tp, flags);
851 break;
852 }
853 case TIOCCONS: /* become virtual console */
854 if (*(int *)data) {
855 struct nameidata nid;
856
857 if (constty && constty != tp &&
858 ISSET(constty->t_state, TS_CONNECTED))
859 return (EBUSY);
860
861 /* Ensure user can open the real console. */
862 NDINIT(&nid, LOOKUP, LOCKLEAF | FOLLOW, UIO_SYSSPACE,
863 "/dev/console", td);
864 if ((error = namei(&nid)) != 0)
865 return (error);
866 NDFREE(&nid, NDF_ONLY_PNBUF);
867 error = VOP_ACCESS(nid.ni_vp, VREAD, td->td_ucred, td);
868 vput(nid.ni_vp);
869 if (error)
870 return (error);
871
872 constty = tp;
873 } else if (tp == constty)
874 constty = NULL;
875 break;
876 case TIOCDRAIN: /* wait till output drained */
877 error = ttywait(tp);
878 if (error)
879 return (error);
880 break;
881 case TIOCGETA: { /* get termios struct */
882 struct termios *t = (struct termios *)data;
883
884 bcopy(&tp->t_termios, t, sizeof(struct termios));
885 break;
886 }
887 case TIOCGETD: /* get line discipline */
888 *(int *)data = tp->t_line;
889 break;
890 case TIOCGWINSZ: /* get window size */
891 *(struct winsize *)data = tp->t_winsize;
892 break;
893 case TIOCGPGRP: /* get pgrp of tty */
894 if (!isctty(p, tp))
895 return (ENOTTY);
896 *(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
897 break;
898 #ifdef TIOCHPCL
899 case TIOCHPCL: /* hang up on last close */
900 s = spltty();
901 SET(tp->t_cflag, HUPCL);
902 splx(s);
903 break;
904 #endif
905 case TIOCNXCL: /* reset exclusive use of tty */
906 s = spltty();
907 CLR(tp->t_state, TS_XCLUDE);
908 splx(s);
909 break;
910 case TIOCOUTQ: /* output queue size */
911 *(int *)data = tp->t_outq.c_cc;
912 break;
913 case TIOCSETA: /* set termios struct */
914 case TIOCSETAW: /* drain output, set */
915 case TIOCSETAF: { /* drn out, fls in, set */
916 struct termios *t = (struct termios *)data;
917
918 if (t->c_ispeed == 0)
919 t->c_ispeed = t->c_ospeed;
920 if (t->c_ispeed == 0)
921 t->c_ispeed = tp->t_ospeed;
922 if (t->c_ispeed == 0)
923 return (EINVAL);
924 s = spltty();
925 if (cmd == TIOCSETAW || cmd == TIOCSETAF) {
926 error = ttywait(tp);
927 if (error) {
928 splx(s);
929 return (error);
930 }
931 if (cmd == TIOCSETAF)
932 ttyflush(tp, FREAD);
933 }
934 if (!ISSET(t->c_cflag, CIGNORE)) {
935 /*
936 * Set device hardware.
937 */
938 if (tp->t_param && (error = (*tp->t_param)(tp, t))) {
939 splx(s);
940 return (error);
941 }
942 if (ISSET(t->c_cflag, CLOCAL) &&
943 !ISSET(tp->t_cflag, CLOCAL)) {
944 /*
945 * XXX disconnections would be too hard to
946 * get rid of without this kludge. The only
947 * way to get rid of controlling terminals
948 * is to exit from the session leader.
949 */
950 CLR(tp->t_state, TS_ZOMBIE);
951
952 wakeup(TSA_CARR_ON(tp));
953 ttwakeup(tp);
954 ttwwakeup(tp);
955 }
956 if ((ISSET(tp->t_state, TS_CARR_ON) ||
957 ISSET(t->c_cflag, CLOCAL)) &&
958 !ISSET(tp->t_state, TS_ZOMBIE))
959 SET(tp->t_state, TS_CONNECTED);
960 else
961 CLR(tp->t_state, TS_CONNECTED);
962 tp->t_cflag = t->c_cflag;
963 tp->t_ispeed = t->c_ispeed;
964 if (t->c_ospeed != 0)
965 tp->t_ospeed = t->c_ospeed;
966 ttsetwater(tp);
967 }
968 if (ISSET(t->c_lflag, ICANON) != ISSET(tp->t_lflag, ICANON) &&
969 cmd != TIOCSETAF) {
970 if (ISSET(t->c_lflag, ICANON))
971 SET(tp->t_lflag, PENDIN);
972 else {
973 /*
974 * XXX we really shouldn't allow toggling
975 * ICANON while we're in a non-termios line
976 * discipline. Now we have to worry about
977 * panicing for a null queue.
978 */
979 if (tp->t_canq.c_cbreserved > 0 &&
980 tp->t_rawq.c_cbreserved > 0) {
981 catq(&tp->t_rawq, &tp->t_canq);
982 /*
983 * XXX the queue limits may be
984 * different, so the old queue
985 * swapping method no longer works.
986 */
987 catq(&tp->t_canq, &tp->t_rawq);
988 }
989 CLR(tp->t_lflag, PENDIN);
990 }
991 ttwakeup(tp);
992 }
993 tp->t_iflag = t->c_iflag;
994 tp->t_oflag = t->c_oflag;
995 /*
996 * Make the EXTPROC bit read only.
997 */
998 if (ISSET(tp->t_lflag, EXTPROC))
999 SET(t->c_lflag, EXTPROC);
1000 else
1001 CLR(t->c_lflag, EXTPROC);
1002 tp->t_lflag = t->c_lflag | ISSET(tp->t_lflag, PENDIN);
1003 if (t->c_cc[VMIN] != tp->t_cc[VMIN] ||
1004 t->c_cc[VTIME] != tp->t_cc[VTIME])
1005 ttwakeup(tp);
1006 bcopy(t->c_cc, tp->t_cc, sizeof(t->c_cc));
1007 splx(s);
1008 break;
1009 }
1010 case TIOCSETD: { /* set line discipline */
1011 int t = *(int *)data;
1012 dev_t device = tp->t_dev;
1013
1014 if ((u_int)t >= nlinesw)
1015 return (ENXIO);
1016 if (t != tp->t_line) {
1017 s = spltty();
1018 (*linesw[tp->t_line].l_close)(tp, flag);
1019 error = (*linesw[t].l_open)(device, tp);
1020 if (error) {
1021 (void)(*linesw[tp->t_line].l_open)(device, tp);
1022 splx(s);
1023 return (error);
1024 }
1025 tp->t_line = t;
1026 splx(s);
1027 }
1028 break;
1029 }
1030 case TIOCSTART: /* start output, like ^Q */
1031 s = spltty();
1032 if (ISSET(tp->t_state, TS_TTSTOP) ||
1033 ISSET(tp->t_lflag, FLUSHO)) {
1034 CLR(tp->t_lflag, FLUSHO);
1035 CLR(tp->t_state, TS_TTSTOP);
1036 ttstart(tp);
1037 }
1038 splx(s);
1039 break;
1040 case TIOCSTI: /* simulate terminal input */
1041 if ((flag & FREAD) == 0 && suser(td))
1042 return (EPERM);
1043 if (!isctty(p, tp) && suser(td))
1044 return (EACCES);
1045 s = spltty();
1046 (*linesw[tp->t_line].l_rint)(*(u_char *)data, tp);
1047 splx(s);
1048 break;
1049 case TIOCSTOP: /* stop output, like ^S */
1050 s = spltty();
1051 if (!ISSET(tp->t_state, TS_TTSTOP)) {
1052 SET(tp->t_state, TS_TTSTOP);
1053 (*tp->t_stop)(tp, 0);
1054 }
1055 splx(s);
1056 break;
1057 case TIOCSCTTY: /* become controlling tty */
1058 /* Session ctty vnode pointer set in vnode layer. */
1059 sx_slock(&proctree_lock);
1060 if (!SESS_LEADER(p) ||
1061 ((p->p_session->s_ttyvp || tp->t_session) &&
1062 (tp->t_session != p->p_session))) {
1063 sx_sunlock(&proctree_lock);
1064 return (EPERM);
1065 }
1066 tp->t_session = p->p_session;
1067 tp->t_pgrp = p->p_pgrp;
1068 SESS_LOCK(p->p_session);
1069 p->p_session->s_ttyp = tp;
1070 SESS_UNLOCK(p->p_session);
1071 PROC_LOCK(p);
1072 p->p_flag |= P_CONTROLT;
1073 PROC_UNLOCK(p);
1074 sx_sunlock(&proctree_lock);
1075 break;
1076 case TIOCSPGRP: { /* set pgrp of tty */
1077 sx_slock(&proctree_lock);
1078 pgrp = pgfind(*(int *)data);
1079 if (!isctty(p, tp)) {
1080 if (pgrp != NULL)
1081 PGRP_UNLOCK(pgrp);
1082 sx_sunlock(&proctree_lock);
1083 return (ENOTTY);
1084 }
1085 if (pgrp == NULL) {
1086 sx_sunlock(&proctree_lock);
1087 return (EPERM);
1088 }
1089 PGRP_UNLOCK(pgrp);
1090 if (pgrp->pg_session != p->p_session) {
1091 sx_sunlock(&proctree_lock);
1092 return (EPERM);
1093 }
1094 sx_sunlock(&proctree_lock);
1095 tp->t_pgrp = pgrp;
1096 break;
1097 }
1098 case TIOCSTAT: /* simulate control-T */
1099 s = spltty();
1100 ttyinfo(tp);
1101 splx(s);
1102 break;
1103 case TIOCSWINSZ: /* set window size */
1104 if (bcmp((caddr_t)&tp->t_winsize, data,
1105 sizeof (struct winsize))) {
1106 tp->t_winsize = *(struct winsize *)data;
1107 if (tp->t_pgrp != NULL) {
1108 PGRP_LOCK(tp->t_pgrp);
1109 pgsignal(tp->t_pgrp, SIGWINCH, 1);
1110 PGRP_UNLOCK(tp->t_pgrp);
1111 }
1112 }
1113 break;
1114 case TIOCSDRAINWAIT:
1115 error = suser(td);
1116 if (error)
1117 return (error);
1118 tp->t_timeout = *(int *)data * hz;
1119 wakeup(TSA_OCOMPLETE(tp));
1120 wakeup(TSA_OLOWAT(tp));
1121 break;
1122 case TIOCGDRAINWAIT:
1123 *(int *)data = tp->t_timeout / hz;
1124 break;
1125 default:
1126 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
1127 return (ttcompat(tp, cmd, data, flag));
1128 #else
1129 return (ENOIOCTL);
1130 #endif
1131 }
1132 return (0);
1133 }
1134
1135 int
1136 ttypoll(dev_t dev, int events, struct thread *td)
1137 {
1138 int s;
1139 int revents = 0;
1140 struct tty *tp;
1141
1142 tp = dev->si_tty;
1143 if (tp == NULL) /* XXX used to return ENXIO, but that means true! */
1144 return ((events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM))
1145 | POLLHUP);
1146
1147 s = spltty();
1148 if (events & (POLLIN | POLLRDNORM)) {
1149 if (ttnread(tp) > 0 || ISSET(tp->t_state, TS_ZOMBIE))
1150 revents |= events & (POLLIN | POLLRDNORM);
1151 else
1152 selrecord(td, &tp->t_rsel);
1153 }
1154 if (events & (POLLOUT | POLLWRNORM)) {
1155 if ((tp->t_outq.c_cc <= tp->t_olowat &&
1156 ISSET(tp->t_state, TS_CONNECTED))
1157 || ISSET(tp->t_state, TS_ZOMBIE))
1158 revents |= events & (POLLOUT | POLLWRNORM);
1159 else
1160 selrecord(td, &tp->t_wsel);
1161 }
1162 splx(s);
1163 return (revents);
1164 }
1165
1166 static struct filterops ttyread_filtops =
1167 { 1, NULL, filt_ttyrdetach, filt_ttyread };
1168 static struct filterops ttywrite_filtops =
1169 { 1, NULL, filt_ttywdetach, filt_ttywrite };
1170
1171 int
1172 ttykqfilter(dev_t dev, struct knote *kn)
1173 {
1174 struct tty *tp = dev->si_tty;
1175 struct klist *klist;
1176 int s;
1177
1178 switch (kn->kn_filter) {
1179 case EVFILT_READ:
1180 klist = &tp->t_rsel.si_note;
1181 kn->kn_fop = &ttyread_filtops;
1182 break;
1183 case EVFILT_WRITE:
1184 klist = &tp->t_wsel.si_note;
1185 kn->kn_fop = &ttywrite_filtops;
1186 break;
1187 default:
1188 return (1);
1189 }
1190
1191 kn->kn_hook = (caddr_t)dev;
1192
1193 s = spltty();
1194 SLIST_INSERT_HEAD(klist, kn, kn_selnext);
1195 splx(s);
1196
1197 return (0);
1198 }
1199
1200 static void
1201 filt_ttyrdetach(struct knote *kn)
1202 {
1203 struct tty *tp = ((dev_t)kn->kn_hook)->si_tty;
1204 int s = spltty();
1205
1206 SLIST_REMOVE(&tp->t_rsel.si_note, kn, knote, kn_selnext);
1207 splx(s);
1208 }
1209
1210 static int
1211 filt_ttyread(struct knote *kn, long hint)
1212 {
1213 struct tty *tp = ((dev_t)kn->kn_hook)->si_tty;
1214
1215 kn->kn_data = ttnread(tp);
1216 if (ISSET(tp->t_state, TS_ZOMBIE)) {
1217 kn->kn_flags |= EV_EOF;
1218 return (1);
1219 }
1220 return (kn->kn_data > 0);
1221 }
1222
1223 static void
1224 filt_ttywdetach(struct knote *kn)
1225 {
1226 struct tty *tp = ((dev_t)kn->kn_hook)->si_tty;
1227 int s = spltty();
1228
1229 SLIST_REMOVE(&tp->t_wsel.si_note, kn, knote, kn_selnext);
1230 splx(s);
1231 }
1232
1233 static int
1234 filt_ttywrite(struct knote *kn, long hint)
1235 {
1236 struct tty *tp = ((dev_t)kn->kn_hook)->si_tty;
1237
1238 kn->kn_data = tp->t_outq.c_cc;
1239 if (ISSET(tp->t_state, TS_ZOMBIE))
1240 return (1);
1241 return (kn->kn_data <= tp->t_olowat &&
1242 ISSET(tp->t_state, TS_CONNECTED));
1243 }
1244
1245 /*
1246 * Must be called at spltty().
1247 */
1248 static int
1249 ttnread(struct tty *tp)
1250 {
1251 int nread;
1252
1253 if (ISSET(tp->t_lflag, PENDIN))
1254 ttypend(tp);
1255 nread = tp->t_canq.c_cc;
1256 if (!ISSET(tp->t_lflag, ICANON)) {
1257 nread += tp->t_rawq.c_cc;
1258 if (nread < tp->t_cc[VMIN] && tp->t_cc[VTIME] == 0)
1259 nread = 0;
1260 }
1261 return (nread);
1262 }
1263
1264 /*
1265 * Wait for output to drain.
1266 */
1267 int
1268 ttywait(struct tty *tp)
1269 {
1270 int error, s;
1271
1272 error = 0;
1273 s = spltty();
1274 while ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
1275 ISSET(tp->t_state, TS_CONNECTED) && tp->t_oproc) {
1276 (*tp->t_oproc)(tp);
1277 if ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
1278 ISSET(tp->t_state, TS_CONNECTED)) {
1279 SET(tp->t_state, TS_SO_OCOMPLETE);
1280 error = ttysleep(tp, TSA_OCOMPLETE(tp),
1281 TTOPRI | PCATCH, "ttywai",
1282 tp->t_timeout);
1283 if (error) {
1284 if (error == EWOULDBLOCK)
1285 error = EIO;
1286 break;
1287 }
1288 } else
1289 break;
1290 }
1291 if (!error && (tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)))
1292 error = EIO;
1293 splx(s);
1294 return (error);
1295 }
1296
1297 /*
1298 * Flush if successfully wait.
1299 */
1300 static int
1301 ttywflush(struct tty *tp)
1302 {
1303 int error;
1304
1305 if ((error = ttywait(tp)) == 0)
1306 ttyflush(tp, FREAD);
1307 return (error);
1308 }
1309
1310 /*
1311 * Flush tty read and/or write queues, notifying anyone waiting.
1312 */
1313 void
1314 ttyflush(struct tty *tp, int rw)
1315 {
1316 int s;
1317
1318 s = spltty();
1319 #if 0
1320 again:
1321 #endif
1322 if (rw & FWRITE) {
1323 FLUSHQ(&tp->t_outq);
1324 CLR(tp->t_state, TS_TTSTOP);
1325 }
1326 (*tp->t_stop)(tp, rw);
1327 if (rw & FREAD) {
1328 FLUSHQ(&tp->t_canq);
1329 FLUSHQ(&tp->t_rawq);
1330 CLR(tp->t_lflag, PENDIN);
1331 tp->t_rocount = 0;
1332 tp->t_rocol = 0;
1333 CLR(tp->t_state, TS_LOCAL);
1334 ttwakeup(tp);
1335 if (ISSET(tp->t_state, TS_TBLOCK)) {
1336 if (rw & FWRITE)
1337 FLUSHQ(&tp->t_outq);
1338 ttyunblock(tp);
1339
1340 /*
1341 * Don't let leave any state that might clobber the
1342 * next line discipline (although we should do more
1343 * to send the START char). Not clearing the state
1344 * may have caused the "putc to a clist with no
1345 * reserved cblocks" panic/printf.
1346 */
1347 CLR(tp->t_state, TS_TBLOCK);
1348
1349 #if 0 /* forget it, sleeping isn't always safe and we don't know when it is */
1350 if (ISSET(tp->t_iflag, IXOFF)) {
1351 /*
1352 * XXX wait a bit in the hope that the stop
1353 * character (if any) will go out. Waiting
1354 * isn't good since it allows races. This
1355 * will be fixed when the stop character is
1356 * put in a special queue. Don't bother with
1357 * the checks in ttywait() since the timeout
1358 * will save us.
1359 */
1360 SET(tp->t_state, TS_SO_OCOMPLETE);
1361 ttysleep(tp, TSA_OCOMPLETE(tp), TTOPRI,
1362 "ttyfls", hz / 10);
1363 /*
1364 * Don't try sending the stop character again.
1365 */
1366 CLR(tp->t_state, TS_TBLOCK);
1367 goto again;
1368 }
1369 #endif
1370 }
1371 }
1372 if (rw & FWRITE) {
1373 FLUSHQ(&tp->t_outq);
1374 ttwwakeup(tp);
1375 }
1376 splx(s);
1377 }
1378
1379 /*
1380 * Copy in the default termios characters.
1381 */
1382 void
1383 termioschars(struct termios *t)
1384 {
1385
1386 bcopy(ttydefchars, t->c_cc, sizeof t->c_cc);
1387 }
1388
1389 /*
1390 * Old interface.
1391 */
1392 void
1393 ttychars(struct tty *tp)
1394 {
1395
1396 termioschars(&tp->t_termios);
1397 }
1398
1399 /*
1400 * Handle input high water. Send stop character for the IXOFF case. Turn
1401 * on our input flow control bit and propagate the changes to the driver.
1402 * XXX the stop character should be put in a special high priority queue.
1403 */
1404 void
1405 ttyblock(struct tty *tp)
1406 {
1407
1408 SET(tp->t_state, TS_TBLOCK);
1409 if (ISSET(tp->t_iflag, IXOFF) && tp->t_cc[VSTOP] != _POSIX_VDISABLE &&
1410 putc(tp->t_cc[VSTOP], &tp->t_outq) != 0)
1411 CLR(tp->t_state, TS_TBLOCK); /* try again later */
1412 ttstart(tp);
1413 }
1414
1415 /*
1416 * Handle input low water. Send start character for the IXOFF case. Turn
1417 * off our input flow control bit and propagate the changes to the driver.
1418 * XXX the start character should be put in a special high priority queue.
1419 */
1420 static void
1421 ttyunblock(struct tty *tp)
1422 {
1423
1424 CLR(tp->t_state, TS_TBLOCK);
1425 if (ISSET(tp->t_iflag, IXOFF) && tp->t_cc[VSTART] != _POSIX_VDISABLE &&
1426 putc(tp->t_cc[VSTART], &tp->t_outq) != 0)
1427 SET(tp->t_state, TS_TBLOCK); /* try again later */
1428 ttstart(tp);
1429 }
1430
1431 #ifdef notyet
1432 /* Not used by any current (i386) drivers. */
1433 /*
1434 * Restart after an inter-char delay.
1435 */
1436 void
1437 ttrstrt(void *tp_arg)
1438 {
1439 struct tty *tp;
1440 int s;
1441
1442 KASSERT(tp_arg != NULL, ("ttrstrt"));
1443
1444 tp = tp_arg;
1445 s = spltty();
1446
1447 CLR(tp->t_state, TS_TIMEOUT);
1448 ttstart(tp);
1449
1450 splx(s);
1451 }
1452 #endif
1453
1454 int
1455 ttstart(struct tty *tp)
1456 {
1457
1458 if (tp->t_oproc != NULL) /* XXX: Kludge for pty. */
1459 (*tp->t_oproc)(tp);
1460 return (0);
1461 }
1462
1463 /*
1464 * "close" a line discipline
1465 */
1466 int
1467 ttylclose(struct tty *tp, int flag)
1468 {
1469
1470 if (flag & FNONBLOCK || ttywflush(tp))
1471 ttyflush(tp, FREAD | FWRITE);
1472 return (0);
1473 }
1474
1475 /*
1476 * Handle modem control transition on a tty.
1477 * Flag indicates new state of carrier.
1478 * Returns 0 if the line should be turned off, otherwise 1.
1479 */
1480 int
1481 ttymodem(struct tty *tp, int flag)
1482 {
1483
1484 if (ISSET(tp->t_state, TS_CARR_ON) && ISSET(tp->t_cflag, MDMBUF)) {
1485 /*
1486 * MDMBUF: do flow control according to carrier flag
1487 * XXX TS_CAR_OFLOW doesn't do anything yet. TS_TTSTOP
1488 * works if IXON and IXANY are clear.
1489 */
1490 if (flag) {
1491 CLR(tp->t_state, TS_CAR_OFLOW);
1492 CLR(tp->t_state, TS_TTSTOP);
1493 ttstart(tp);
1494 } else if (!ISSET(tp->t_state, TS_CAR_OFLOW)) {
1495 SET(tp->t_state, TS_CAR_OFLOW);
1496 SET(tp->t_state, TS_TTSTOP);
1497 (*tp->t_stop)(tp, 0);
1498 }
1499 } else if (flag == 0) {
1500 /*
1501 * Lost carrier.
1502 */
1503 CLR(tp->t_state, TS_CARR_ON);
1504 if (ISSET(tp->t_state, TS_ISOPEN) &&
1505 !ISSET(tp->t_cflag, CLOCAL)) {
1506 SET(tp->t_state, TS_ZOMBIE);
1507 CLR(tp->t_state, TS_CONNECTED);
1508 if (tp->t_session) {
1509 sx_slock(&proctree_lock);
1510 if (tp->t_session->s_leader) {
1511 struct proc *p;
1512
1513 p = tp->t_session->s_leader;
1514 PROC_LOCK(p);
1515 psignal(p, SIGHUP);
1516 PROC_UNLOCK(p);
1517 }
1518 sx_sunlock(&proctree_lock);
1519 }
1520 ttyflush(tp, FREAD | FWRITE);
1521 return (0);
1522 }
1523 } else {
1524 /*
1525 * Carrier now on.
1526 */
1527 SET(tp->t_state, TS_CARR_ON);
1528 if (!ISSET(tp->t_state, TS_ZOMBIE))
1529 SET(tp->t_state, TS_CONNECTED);
1530 wakeup(TSA_CARR_ON(tp));
1531 ttwakeup(tp);
1532 ttwwakeup(tp);
1533 }
1534 return (1);
1535 }
1536
1537 /*
1538 * Reinput pending characters after state switch
1539 * call at spltty().
1540 */
1541 static void
1542 ttypend(struct tty *tp)
1543 {
1544 struct clist tq;
1545 int c;
1546
1547 CLR(tp->t_lflag, PENDIN);
1548 SET(tp->t_state, TS_TYPEN);
1549 /*
1550 * XXX this assumes too much about clist internals. It may even
1551 * fail if the cblock slush pool is empty. We can't allocate more
1552 * cblocks here because we are called from an interrupt handler
1553 * and clist_alloc_cblocks() can wait.
1554 */
1555 tq = tp->t_rawq;
1556 bzero(&tp->t_rawq, sizeof tp->t_rawq);
1557 tp->t_rawq.c_cbmax = tq.c_cbmax;
1558 tp->t_rawq.c_cbreserved = tq.c_cbreserved;
1559 while ((c = getc(&tq)) >= 0)
1560 ttyinput(c, tp);
1561 CLR(tp->t_state, TS_TYPEN);
1562 }
1563
1564 /*
1565 * Process a read call on a tty device.
1566 */
1567 int
1568 ttread(struct tty *tp, struct uio *uio, int flag)
1569 {
1570 struct clist *qp;
1571 int c;
1572 tcflag_t lflag;
1573 cc_t *cc = tp->t_cc;
1574 struct thread *td;
1575 struct proc *p;
1576 int s, first, error = 0;
1577 int has_stime = 0, last_cc = 0;
1578 long slp = 0; /* XXX this should be renamed `timo'. */
1579 struct timeval stime;
1580 struct pgrp *pg;
1581
1582 td = curthread;
1583 p = td->td_proc;
1584 loop:
1585 s = spltty();
1586 lflag = tp->t_lflag;
1587 /*
1588 * take pending input first
1589 */
1590 if (ISSET(lflag, PENDIN)) {
1591 ttypend(tp);
1592 splx(s); /* reduce latency */
1593 s = spltty();
1594 lflag = tp->t_lflag; /* XXX ttypend() clobbers it */
1595 }
1596
1597 /*
1598 * Hang process if it's in the background.
1599 */
1600 if (isbackground(p, tp)) {
1601 splx(s);
1602 sx_slock(&proctree_lock);
1603 PROC_LOCK(p);
1604 if (SIGISMEMBER(p->p_sigacts->ps_sigignore, SIGTTIN) ||
1605 SIGISMEMBER(td->td_sigmask, SIGTTIN) ||
1606 (p->p_flag & P_PPWAIT) || p->p_pgrp->pg_jobc == 0) {
1607 PROC_UNLOCK(p);
1608 sx_sunlock(&proctree_lock);
1609 return (EIO);
1610 }
1611 pg = p->p_pgrp;
1612 PROC_UNLOCK(p);
1613 PGRP_LOCK(pg);
1614 sx_sunlock(&proctree_lock);
1615 pgsignal(pg, SIGTTIN, 1);
1616 PGRP_UNLOCK(pg);
1617 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, "ttybg2", 0);
1618 if (error)
1619 return (error);
1620 goto loop;
1621 }
1622
1623 if (ISSET(tp->t_state, TS_ZOMBIE)) {
1624 splx(s);
1625 return (0); /* EOF */
1626 }
1627
1628 /*
1629 * If canonical, use the canonical queue,
1630 * else use the raw queue.
1631 *
1632 * (should get rid of clists...)
1633 */
1634 qp = ISSET(lflag, ICANON) ? &tp->t_canq : &tp->t_rawq;
1635
1636 if (flag & IO_NDELAY) {
1637 if (qp->c_cc > 0)
1638 goto read;
1639 if (!ISSET(lflag, ICANON) && cc[VMIN] == 0) {
1640 splx(s);
1641 return (0);
1642 }
1643 splx(s);
1644 return (EWOULDBLOCK);
1645 }
1646 if (!ISSET(lflag, ICANON)) {
1647 int m = cc[VMIN];
1648 long t = cc[VTIME];
1649 struct timeval timecopy;
1650
1651 /*
1652 * Check each of the four combinations.
1653 * (m > 0 && t == 0) is the normal read case.
1654 * It should be fairly efficient, so we check that and its
1655 * companion case (m == 0 && t == 0) first.
1656 * For the other two cases, we compute the target sleep time
1657 * into slp.
1658 */
1659 if (t == 0) {
1660 if (qp->c_cc < m)
1661 goto sleep;
1662 if (qp->c_cc > 0)
1663 goto read;
1664
1665 /* m, t and qp->c_cc are all 0. 0 is enough input. */
1666 splx(s);
1667 return (0);
1668 }
1669 t *= 100000; /* time in us */
1670 #define diff(t1, t2) (((t1).tv_sec - (t2).tv_sec) * 1000000 + \
1671 ((t1).tv_usec - (t2).tv_usec))
1672 if (m > 0) {
1673 if (qp->c_cc <= 0)
1674 goto sleep;
1675 if (qp->c_cc >= m)
1676 goto read;
1677 getmicrotime(&timecopy);
1678 if (!has_stime) {
1679 /* first character, start timer */
1680 has_stime = 1;
1681 stime = timecopy;
1682 slp = t;
1683 } else if (qp->c_cc > last_cc) {
1684 /* got a character, restart timer */
1685 stime = timecopy;
1686 slp = t;
1687 } else {
1688 /* nothing, check expiration */
1689 slp = t - diff(timecopy, stime);
1690 if (slp <= 0)
1691 goto read;
1692 }
1693 last_cc = qp->c_cc;
1694 } else { /* m == 0 */
1695 if (qp->c_cc > 0)
1696 goto read;
1697 getmicrotime(&timecopy);
1698 if (!has_stime) {
1699 has_stime = 1;
1700 stime = timecopy;
1701 slp = t;
1702 } else {
1703 slp = t - diff(timecopy, stime);
1704 if (slp <= 0) {
1705 /* Timed out, but 0 is enough input. */
1706 splx(s);
1707 return (0);
1708 }
1709 }
1710 }
1711 #undef diff
1712 /*
1713 * Rounding down may make us wake up just short
1714 * of the target, so we round up.
1715 * The formula is ceiling(slp * hz/1000000).
1716 * 32-bit arithmetic is enough for hz < 169.
1717 * XXX see tvtohz() for how to avoid overflow if hz
1718 * is large (divide by `tick' and/or arrange to
1719 * use tvtohz() if hz is large).
1720 */
1721 slp = (long) (((u_long)slp * hz) + 999999) / 1000000;
1722 goto sleep;
1723 }
1724 if (qp->c_cc <= 0) {
1725 sleep:
1726 /*
1727 * There is no input, or not enough input and we can block.
1728 */
1729 error = ttysleep(tp, TSA_HUP_OR_INPUT(tp), TTIPRI | PCATCH,
1730 ISSET(tp->t_state, TS_CONNECTED) ?
1731 "ttyin" : "ttyhup", (int)slp);
1732 splx(s);
1733 if (error == EWOULDBLOCK)
1734 error = 0;
1735 else if (error)
1736 return (error);
1737 /*
1738 * XXX what happens if another process eats some input
1739 * while we are asleep (not just here)? It would be
1740 * safest to detect changes and reset our state variables
1741 * (has_stime and last_cc).
1742 */
1743 slp = 0;
1744 goto loop;
1745 }
1746 read:
1747 splx(s);
1748 /*
1749 * Input present, check for input mapping and processing.
1750 */
1751 first = 1;
1752 if (ISSET(lflag, ICANON | ISIG))
1753 goto slowcase;
1754 for (;;) {
1755 char ibuf[IBUFSIZ];
1756 int icc;
1757
1758 icc = imin(uio->uio_resid, IBUFSIZ);
1759 icc = q_to_b(qp, ibuf, icc);
1760 if (icc <= 0) {
1761 if (first)
1762 goto loop;
1763 break;
1764 }
1765 error = uiomove(ibuf, icc, uio);
1766 /*
1767 * XXX if there was an error then we should ungetc() the
1768 * unmoved chars and reduce icc here.
1769 */
1770 if (error)
1771 break;
1772 if (uio->uio_resid == 0)
1773 break;
1774 first = 0;
1775 }
1776 goto out;
1777 slowcase:
1778 for (;;) {
1779 c = getc(qp);
1780 if (c < 0) {
1781 if (first)
1782 goto loop;
1783 break;
1784 }
1785 /*
1786 * delayed suspend (^Y)
1787 */
1788 if (CCEQ(cc[VDSUSP], c) &&
1789 ISSET(lflag, IEXTEN | ISIG) == (IEXTEN | ISIG)) {
1790 if (tp->t_pgrp != NULL) {
1791 PGRP_LOCK(tp->t_pgrp);
1792 pgsignal(tp->t_pgrp, SIGTSTP, 1);
1793 PGRP_UNLOCK(tp->t_pgrp);
1794 }
1795 if (first) {
1796 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH,
1797 "ttybg3", 0);
1798 if (error)
1799 break;
1800 goto loop;
1801 }
1802 break;
1803 }
1804 /*
1805 * Interpret EOF only in canonical mode.
1806 */
1807 if (CCEQ(cc[VEOF], c) && ISSET(lflag, ICANON))
1808 break;
1809 /*
1810 * Give user character.
1811 */
1812 error = ureadc(c, uio);
1813 if (error)
1814 /* XXX should ungetc(c, qp). */
1815 break;
1816 if (uio->uio_resid == 0)
1817 break;
1818 /*
1819 * In canonical mode check for a "break character"
1820 * marking the end of a "line of input".
1821 */
1822 if (ISSET(lflag, ICANON) && TTBREAKC(c, lflag))
1823 break;
1824 first = 0;
1825 }
1826
1827 out:
1828 /*
1829 * Look to unblock input now that (presumably)
1830 * the input queue has gone down.
1831 */
1832 s = spltty();
1833 if (ISSET(tp->t_state, TS_TBLOCK) &&
1834 tp->t_rawq.c_cc + tp->t_canq.c_cc <= tp->t_ilowat)
1835 ttyunblock(tp);
1836 splx(s);
1837
1838 return (error);
1839 }
1840
1841 /*
1842 * Check the output queue on tp for space for a kernel message (from uprintf
1843 * or tprintf). Allow some space over the normal hiwater mark so we don't
1844 * lose messages due to normal flow control, but don't let the tty run amok.
1845 * Sleeps here are not interruptible, but we return prematurely if new signals
1846 * arrive.
1847 */
1848 int
1849 ttycheckoutq(struct tty *tp, int wait)
1850 {
1851 int hiwat, s;
1852 sigset_t oldmask;
1853 struct thread *td;
1854 struct proc *p;
1855
1856 td = curthread;
1857 p = td->td_proc;
1858 hiwat = tp->t_ohiwat;
1859 SIGEMPTYSET(oldmask);
1860 s = spltty();
1861 if (wait) {
1862 PROC_LOCK(p);
1863 oldmask = td->td_siglist;
1864 PROC_UNLOCK(p);
1865 }
1866 if (tp->t_outq.c_cc > hiwat + OBUFSIZ + 100)
1867 while (tp->t_outq.c_cc > hiwat) {
1868 ttstart(tp);
1869 if (tp->t_outq.c_cc <= hiwat)
1870 break;
1871 if (!wait) {
1872 splx(s);
1873 return (0);
1874 }
1875 PROC_LOCK(p);
1876 if (!SIGSETEQ(td->td_siglist, oldmask)) {
1877 PROC_UNLOCK(p);
1878 splx(s);
1879 return (0);
1880 }
1881 PROC_UNLOCK(p);
1882 SET(tp->t_state, TS_SO_OLOWAT);
1883 tsleep(TSA_OLOWAT(tp), PZERO - 1, "ttoutq", hz);
1884 }
1885 splx(s);
1886 return (1);
1887 }
1888
1889 /*
1890 * Process a write call on a tty device.
1891 */
1892 int
1893 ttwrite(struct tty *tp, struct uio *uio, int flag)
1894 {
1895 char *cp = NULL;
1896 int cc, ce;
1897 struct thread *td;
1898 struct proc *p;
1899 int i, hiwat, cnt, error, s;
1900 char obuf[OBUFSIZ];
1901
1902 hiwat = tp->t_ohiwat;
1903 cnt = uio->uio_resid;
1904 error = 0;
1905 cc = 0;
1906 td = curthread;
1907 p = td->td_proc;
1908 loop:
1909 s = spltty();
1910 if (ISSET(tp->t_state, TS_ZOMBIE)) {
1911 splx(s);
1912 if (uio->uio_resid == cnt)
1913 error = EIO;
1914 goto out;
1915 }
1916 if (!ISSET(tp->t_state, TS_CONNECTED)) {
1917 if (flag & IO_NDELAY) {
1918 splx(s);
1919 error = EWOULDBLOCK;
1920 goto out;
1921 }
1922 error = ttysleep(tp, TSA_CARR_ON(tp), TTIPRI | PCATCH,
1923 "ttydcd", 0);
1924 splx(s);
1925 if (error)
1926 goto out;
1927 goto loop;
1928 }
1929 splx(s);
1930 /*
1931 * Hang the process if it's in the background.
1932 */
1933 sx_slock(&proctree_lock);
1934 PROC_LOCK(p);
1935 if (isbackground(p, tp) &&
1936 ISSET(tp->t_lflag, TOSTOP) && !(p->p_flag & P_PPWAIT) &&
1937 !SIGISMEMBER(p->p_sigacts->ps_sigignore, SIGTTOU) &&
1938 !SIGISMEMBER(td->td_sigmask, SIGTTOU)) {
1939 if (p->p_pgrp->pg_jobc == 0) {
1940 PROC_UNLOCK(p);
1941 sx_sunlock(&proctree_lock);
1942 error = EIO;
1943 goto out;
1944 }
1945 PROC_UNLOCK(p);
1946 PGRP_LOCK(p->p_pgrp);
1947 sx_sunlock(&proctree_lock);
1948 pgsignal(p->p_pgrp, SIGTTOU, 1);
1949 PGRP_UNLOCK(p->p_pgrp);
1950 error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, "ttybg4", 0);
1951 if (error)
1952 goto out;
1953 goto loop;
1954 } else {
1955 PROC_UNLOCK(p);
1956 sx_sunlock(&proctree_lock);
1957 }
1958 /*
1959 * Process the user's data in at most OBUFSIZ chunks. Perform any
1960 * output translation. Keep track of high water mark, sleep on
1961 * overflow awaiting device aid in acquiring new space.
1962 */
1963 while (uio->uio_resid > 0 || cc > 0) {
1964 if (ISSET(tp->t_lflag, FLUSHO)) {
1965 uio->uio_resid = 0;
1966 return (0);
1967 }
1968 if (tp->t_outq.c_cc > hiwat)
1969 goto ovhiwat;
1970 /*
1971 * Grab a hunk of data from the user, unless we have some
1972 * leftover from last time.
1973 */
1974 if (cc == 0) {
1975 cc = imin(uio->uio_resid, OBUFSIZ);
1976 cp = obuf;
1977 error = uiomove(cp, cc, uio);
1978 if (error) {
1979 cc = 0;
1980 break;
1981 }
1982 }
1983 /*
1984 * If nothing fancy need be done, grab those characters we
1985 * can handle without any of ttyoutput's processing and
1986 * just transfer them to the output q. For those chars
1987 * which require special processing (as indicated by the
1988 * bits in char_type), call ttyoutput. After processing
1989 * a hunk of data, look for FLUSHO so ^O's will take effect
1990 * immediately.
1991 */
1992 while (cc > 0) {
1993 if (!ISSET(tp->t_oflag, OPOST))
1994 ce = cc;
1995 else {
1996 ce = cc - scanc((u_int)cc, (u_char *)cp,
1997 char_type, CCLASSMASK);
1998 /*
1999 * If ce is zero, then we're processing
2000 * a special character through ttyoutput.
2001 */
2002 if (ce == 0) {
2003 tp->t_rocount = 0;
2004 if (ttyoutput(*cp, tp) >= 0) {
2005 /* No Clists, wait a bit. */
2006 ttstart(tp);
2007 if (flag & IO_NDELAY) {
2008 error = EWOULDBLOCK;
2009 goto out;
2010 }
2011 error = ttysleep(tp, &lbolt,
2012 TTOPRI|PCATCH,
2013 "ttybf1", 0);
2014 if (error)
2015 goto out;
2016 goto loop;
2017 }
2018 cp++;
2019 cc--;
2020 if (ISSET(tp->t_lflag, FLUSHO) ||
2021 tp->t_outq.c_cc > hiwat)
2022 goto ovhiwat;
2023 continue;
2024 }
2025 }
2026 /*
2027 * A bunch of normal characters have been found.
2028 * Transfer them en masse to the output queue and
2029 * continue processing at the top of the loop.
2030 * If there are any further characters in this
2031 * <= OBUFSIZ chunk, the first should be a character
2032 * requiring special handling by ttyoutput.
2033 */
2034 tp->t_rocount = 0;
2035 i = b_to_q(cp, ce, &tp->t_outq);
2036 ce -= i;
2037 tp->t_column += ce;
2038 cp += ce, cc -= ce, tk_nout += ce;
2039 tp->t_outcc += ce;
2040 if (i > 0) {
2041 /* No Clists, wait a bit. */
2042 ttstart(tp);
2043 if (flag & IO_NDELAY) {
2044 error = EWOULDBLOCK;
2045 goto out;
2046 }
2047 error = ttysleep(tp, &lbolt, TTOPRI | PCATCH,
2048 "ttybf2", 0);
2049 if (error)
2050 goto out;
2051 goto loop;
2052 }
2053 if (ISSET(tp->t_lflag, FLUSHO) ||
2054 tp->t_outq.c_cc > hiwat)
2055 break;
2056 }
2057 ttstart(tp);
2058 }
2059 out:
2060 /*
2061 * If cc is nonzero, we leave the uio structure inconsistent, as the
2062 * offset and iov pointers have moved forward, but it doesn't matter
2063 * (the call will either return short or restart with a new uio).
2064 */
2065 uio->uio_resid += cc;
2066 return (error);
2067
2068 ovhiwat:
2069 ttstart(tp);
2070 s = spltty();
2071 /*
2072 * This can only occur if FLUSHO is set in t_lflag,
2073 * or if ttstart/oproc is synchronous (or very fast).
2074 */
2075 if (tp->t_outq.c_cc <= hiwat) {
2076 splx(s);
2077 goto loop;
2078 }
2079 if (flag & IO_NDELAY) {
2080 splx(s);
2081 uio->uio_resid += cc;
2082 return (uio->uio_resid == cnt ? EWOULDBLOCK : 0);
2083 }
2084 SET(tp->t_state, TS_SO_OLOWAT);
2085 error = ttysleep(tp, TSA_OLOWAT(tp), TTOPRI | PCATCH, "ttywri",
2086 tp->t_timeout);
2087 splx(s);
2088 if (error == EWOULDBLOCK)
2089 error = EIO;
2090 if (error)
2091 goto out;
2092 goto loop;
2093 }
2094
2095 /*
2096 * Rubout one character from the rawq of tp
2097 * as cleanly as possible.
2098 */
2099 static void
2100 ttyrub(int c, struct tty *tp)
2101 {
2102 char *cp;
2103 int savecol;
2104 int tabc, s;
2105
2106 if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC))
2107 return;
2108 CLR(tp->t_lflag, FLUSHO);
2109 if (ISSET(tp->t_lflag, ECHOE)) {
2110 if (tp->t_rocount == 0) {
2111 /*
2112 * Screwed by ttwrite; retype
2113 */
2114 ttyretype(tp);
2115 return;
2116 }
2117 if (c == ('\t' | TTY_QUOTE) || c == ('\n' | TTY_QUOTE))
2118 ttyrubo(tp, 2);
2119 else {
2120 CLR(c, ~TTY_CHARMASK);
2121 switch (CCLASS(c)) {
2122 case ORDINARY:
2123 ttyrubo(tp, 1);
2124 break;
2125 case BACKSPACE:
2126 case CONTROL:
2127 case NEWLINE:
2128 case RETURN:
2129 case VTAB:
2130 if (ISSET(tp->t_lflag, ECHOCTL))
2131 ttyrubo(tp, 2);
2132 break;
2133 case TAB:
2134 if (tp->t_rocount < tp->t_rawq.c_cc) {
2135 ttyretype(tp);
2136 return;
2137 }
2138 s = spltty();
2139 savecol = tp->t_column;
2140 SET(tp->t_state, TS_CNTTB);
2141 SET(tp->t_lflag, FLUSHO);
2142 tp->t_column = tp->t_rocol;
2143 cp = tp->t_rawq.c_cf;
2144 if (cp)
2145 tabc = *cp; /* XXX FIX NEXTC */
2146 for (; cp; cp = nextc(&tp->t_rawq, cp, &tabc))
2147 ttyecho(tabc, tp);
2148 CLR(tp->t_lflag, FLUSHO);
2149 CLR(tp->t_state, TS_CNTTB);
2150 splx(s);
2151
2152 /* savecol will now be length of the tab. */
2153 savecol -= tp->t_column;
2154 tp->t_column += savecol;
2155 if (savecol > 8)
2156 savecol = 8; /* overflow screw */
2157 while (--savecol >= 0)
2158 (void)ttyoutput('\b', tp);
2159 break;
2160 default: /* XXX */
2161 #define PANICSTR "ttyrub: would panic c = %d, val = %d\n"
2162 (void)printf(PANICSTR, c, CCLASS(c));
2163 #ifdef notdef
2164 panic(PANICSTR, c, CCLASS(c));
2165 #endif
2166 }
2167 }
2168 } else if (ISSET(tp->t_lflag, ECHOPRT)) {
2169 if (!ISSET(tp->t_state, TS_ERASE)) {
2170 SET(tp->t_state, TS_ERASE);
2171 (void)ttyoutput('\\', tp);
2172 }
2173 ttyecho(c, tp);
2174 } else {
2175 ttyecho(tp->t_cc[VERASE], tp);
2176 /*
2177 * This code may be executed not only when an ERASE key
2178 * is pressed, but also when ^U (KILL) or ^W (WERASE) are.
2179 * So, I didn't think it was worthwhile to pass the extra
2180 * information (which would need an extra parameter,
2181 * changing every call) needed to distinguish the ERASE2
2182 * case from the ERASE.
2183 */
2184 }
2185 --tp->t_rocount;
2186 }
2187
2188 /*
2189 * Back over cnt characters, erasing them.
2190 */
2191 static void
2192 ttyrubo(struct tty *tp, int cnt)
2193 {
2194
2195 while (cnt-- > 0) {
2196 (void)ttyoutput('\b', tp);
2197 (void)ttyoutput(' ', tp);
2198 (void)ttyoutput('\b', tp);
2199 }
2200 }
2201
2202 /*
2203 * ttyretype --
2204 * Reprint the rawq line. Note, it is assumed that c_cc has already
2205 * been checked.
2206 */
2207 static void
2208 ttyretype(struct tty *tp)
2209 {
2210 char *cp;
2211 int s, c;
2212
2213 /* Echo the reprint character. */
2214 if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE)
2215 ttyecho(tp->t_cc[VREPRINT], tp);
2216
2217 (void)ttyoutput('\n', tp);
2218
2219 /*
2220 * XXX
2221 * FIX: NEXTC IS BROKEN - DOESN'T CHECK QUOTE
2222 * BIT OF FIRST CHAR.
2223 */
2224 s = spltty();
2225 for (cp = tp->t_canq.c_cf, c = (cp != NULL ? *cp : 0);
2226 cp != NULL; cp = nextc(&tp->t_canq, cp, &c))
2227 ttyecho(c, tp);
2228 for (cp = tp->t_rawq.c_cf, c = (cp != NULL ? *cp : 0);
2229 cp != NULL; cp = nextc(&tp->t_rawq, cp, &c))
2230 ttyecho(c, tp);
2231 CLR(tp->t_state, TS_ERASE);
2232 splx(s);
2233
2234 tp->t_rocount = tp->t_rawq.c_cc;
2235 tp->t_rocol = 0;
2236 }
2237
2238 /*
2239 * Echo a typed character to the terminal.
2240 */
2241 static void
2242 ttyecho(int c, struct tty *tp)
2243 {
2244
2245 if (!ISSET(tp->t_state, TS_CNTTB))
2246 CLR(tp->t_lflag, FLUSHO);
2247 if ((!ISSET(tp->t_lflag, ECHO) &&
2248 (c != '\n' || !ISSET(tp->t_lflag, ECHONL))) ||
2249 ISSET(tp->t_lflag, EXTPROC))
2250 return;
2251 if (ISSET(tp->t_lflag, ECHOCTL) &&
2252 ((ISSET(c, TTY_CHARMASK) <= 037 && c != '\t' && c != '\n') ||
2253 ISSET(c, TTY_CHARMASK) == 0177)) {
2254 (void)ttyoutput('^', tp);
2255 CLR(c, ~TTY_CHARMASK);
2256 if (c == 0177)
2257 c = '?';
2258 else
2259 c += 'A' - 1;
2260 }
2261 (void)ttyoutput(c, tp);
2262 }
2263
2264 /*
2265 * Wake up any readers on a tty.
2266 */
2267 void
2268 ttwakeup(struct tty *tp)
2269 {
2270
2271 if (SEL_WAITING(&tp->t_rsel))
2272 selwakeup(&tp->t_rsel);
2273 if (ISSET(tp->t_state, TS_ASYNC) && tp->t_sigio != NULL)
2274 pgsigio(&tp->t_sigio, SIGIO, (tp->t_session != NULL));
2275 wakeup(TSA_HUP_OR_INPUT(tp));
2276 KNOTE(&tp->t_rsel.si_note, 0);
2277 }
2278
2279 /*
2280 * Wake up any writers on a tty.
2281 */
2282 void
2283 ttwwakeup(struct tty *tp)
2284 {
2285
2286 if (SEL_WAITING(&tp->t_wsel) && tp->t_outq.c_cc <= tp->t_olowat)
2287 selwakeup(&tp->t_wsel);
2288 if (ISSET(tp->t_state, TS_ASYNC) && tp->t_sigio != NULL)
2289 pgsigio(&tp->t_sigio, SIGIO, (tp->t_session != NULL));
2290 if (ISSET(tp->t_state, TS_BUSY | TS_SO_OCOMPLETE) ==
2291 TS_SO_OCOMPLETE && tp->t_outq.c_cc == 0) {
2292 CLR(tp->t_state, TS_SO_OCOMPLETE);
2293 wakeup(TSA_OCOMPLETE(tp));
2294 }
2295 if (ISSET(tp->t_state, TS_SO_OLOWAT) &&
2296 tp->t_outq.c_cc <= tp->t_olowat) {
2297 CLR(tp->t_state, TS_SO_OLOWAT);
2298 wakeup(TSA_OLOWAT(tp));
2299 }
2300 KNOTE(&tp->t_wsel.si_note, 0);
2301 }
2302
2303 /*
2304 * Look up a code for a specified speed in a conversion table;
2305 * used by drivers to map software speed values to hardware parameters.
2306 */
2307 int
2308 ttspeedtab(int speed, struct speedtab *table)
2309 {
2310
2311 for ( ; table->sp_speed != -1; table++)
2312 if (table->sp_speed == speed)
2313 return (table->sp_code);
2314 return (-1);
2315 }
2316
2317 /*
2318 * Set input and output watermarks and buffer sizes. For input, the
2319 * high watermark is about one second's worth of input above empty, the
2320 * low watermark is slightly below high water, and the buffer size is a
2321 * driver-dependent amount above high water. For output, the watermarks
2322 * are near the ends of the buffer, with about 1 second's worth of input
2323 * between them. All this only applies to the standard line discipline.
2324 */
2325 void
2326 ttsetwater(struct tty *tp)
2327 {
2328 int cps, ttmaxhiwat, x;
2329
2330 /* Input. */
2331 clist_alloc_cblocks(&tp->t_canq, TTYHOG, 512);
2332 switch (tp->t_ispeedwat) {
2333 case (speed_t)-1:
2334 cps = tp->t_ispeed / 10;
2335 break;
2336 case 0:
2337 /*
2338 * This case is for old drivers that don't know about
2339 * t_ispeedwat. Arrange for them to get the old buffer
2340 * sizes and watermarks.
2341 */
2342 cps = TTYHOG - 2 * 256;
2343 tp->t_ififosize = 2 * 256;
2344 break;
2345 default:
2346 cps = tp->t_ispeedwat / 10;
2347 break;
2348 }
2349 tp->t_ihiwat = cps;
2350 tp->t_ilowat = 7 * cps / 8;
2351 x = cps + tp->t_ififosize;
2352 clist_alloc_cblocks(&tp->t_rawq, x, x);
2353
2354 /* Output. */
2355 switch (tp->t_ospeedwat) {
2356 case (speed_t)-1:
2357 cps = tp->t_ospeed / 10;
2358 ttmaxhiwat = 2 * TTMAXHIWAT;
2359 break;
2360 case 0:
2361 cps = tp->t_ospeed / 10;
2362 ttmaxhiwat = TTMAXHIWAT;
2363 break;
2364 default:
2365 cps = tp->t_ospeedwat / 10;
2366 ttmaxhiwat = 8 * TTMAXHIWAT;
2367 break;
2368 }
2369 #define CLAMP(x, h, l) ((x) > h ? h : ((x) < l) ? l : (x))
2370 tp->t_olowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT);
2371 x += cps;
2372 x = CLAMP(x, ttmaxhiwat, TTMINHIWAT); /* XXX clamps are too magic */
2373 tp->t_ohiwat = roundup(x, CBSIZE); /* XXX for compat */
2374 x = imax(tp->t_ohiwat, TTMAXHIWAT); /* XXX for compat/safety */
2375 x += OBUFSIZ + 100;
2376 clist_alloc_cblocks(&tp->t_outq, x, x);
2377 #undef CLAMP
2378 }
2379
2380 /*
2381 * Report on state of foreground process group.
2382 */
2383 void
2384 ttyinfo(struct tty *tp)
2385 {
2386 struct proc *p, *pick;
2387 struct timeval utime, stime;
2388 const char *stmp, *sprefix;
2389 long ltmp;
2390 int tmp;
2391 struct thread *td;
2392
2393 if (ttycheckoutq(tp,0) == 0)
2394 return;
2395
2396 /* Print load average. */
2397 tmp = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT;
2398 ttyprintf(tp, "load: %d.%02d ", tmp / 100, tmp % 100);
2399
2400 if (tp->t_session == NULL)
2401 ttyprintf(tp, "not a controlling terminal\n");
2402 else if (tp->t_pgrp == NULL)
2403 ttyprintf(tp, "no foreground process group\n");
2404 else {
2405 PGRP_LOCK(tp->t_pgrp);
2406 if ((p = LIST_FIRST(&tp->t_pgrp->pg_members)) == 0) {
2407 PGRP_UNLOCK(tp->t_pgrp);
2408 ttyprintf(tp, "empty foreground process group\n");
2409 } else {
2410 mtx_lock_spin(&sched_lock);
2411
2412 /* Pick interesting process. */
2413 for (pick = NULL; p != 0; p = LIST_NEXT(p, p_pglist))
2414 if (proc_compare(pick, p))
2415 pick = p;
2416 PGRP_UNLOCK(tp->t_pgrp);
2417
2418 td = FIRST_THREAD_IN_PROC(pick);
2419 sprefix = "";
2420 if (pick->p_flag & P_THREADED) {
2421 stmp = "KSE" ; /* XXXKSE */
2422 } else {
2423 if (td) {
2424 if (TD_ON_RUNQ(td) ||
2425 (TD_IS_RUNNING(td))) {
2426 stmp = "running";
2427 } else if (TD_ON_LOCK(td)) {
2428 stmp = td->td_lockname;
2429 sprefix = "*";
2430 } else if (td->td_wmesg) {
2431 stmp = td->td_wmesg;
2432 } else {
2433 stmp = "iowait";
2434 }
2435 } else {
2436 stmp = "threadless";
2437 panic("ttyinfo: no thread!?");
2438 }
2439 }
2440 calcru(pick, &utime, &stime, NULL);
2441 if (pick->p_state == PRS_NEW ||
2442 pick->p_state == PRS_ZOMBIE) {
2443 ltmp = 0;
2444 } else {
2445 ltmp = pgtok(
2446 vmspace_resident_count(pick->p_vmspace));
2447 }
2448 mtx_unlock_spin(&sched_lock);
2449
2450 ttyprintf(tp, " cmd: %s %d [%s%s] ", pick->p_comm,
2451 pick->p_pid, sprefix, stmp);
2452
2453 /* Print user time. */
2454 ttyprintf(tp, "%ld.%02ldu ",
2455 utime.tv_sec, utime.tv_usec / 10000);
2456
2457 /* Print system time. */
2458 ttyprintf(tp, "%ld.%02lds ",
2459 (long)stime.tv_sec, stime.tv_usec / 10000);
2460
2461 /* Print percentage cpu, resident set size. */
2462 ttyprintf(tp, "%d%% %ldk\n", tmp / 100, ltmp);
2463
2464 }
2465 }
2466 tp->t_rocount = 0; /* so pending input will be retyped if BS */
2467 }
2468
2469 /*
2470 * Returns 1 if p2 is "better" than p1
2471 *
2472 * The algorithm for picking the "interesting" process is thus:
2473 *
2474 * 1) Only foreground processes are eligible - implied.
2475 * 2) Runnable processes are favored over anything else. The runner
2476 * with the highest cpu utilization is picked (p_estcpu). Ties are
2477 * broken by picking the highest pid.
2478 * 3) The sleeper with the shortest sleep time is next. With ties,
2479 * we pick out just "short-term" sleepers (P_SINTR == 0).
2480 * 4) Further ties are broken by picking the highest pid.
2481 */
2482 #define ISRUN(p, val) \
2483 do { \
2484 struct thread *td; \
2485 val = 0; \
2486 FOREACH_THREAD_IN_PROC(p, td) { \
2487 if (TD_ON_RUNQ(td) || \
2488 TD_IS_RUNNING(td)) { \
2489 val = 1; \
2490 break; \
2491 } \
2492 } \
2493 } while (0)
2494
2495 #define TESTAB(a, b) ((a)<<1 | (b))
2496 #define ONLYA 2
2497 #define ONLYB 1
2498 #define BOTH 3
2499
2500 static int
2501 proc_compare(struct proc *p1, struct proc *p2)
2502 {
2503
2504 int esta, estb;
2505 struct ksegrp *kg;
2506 mtx_assert(&sched_lock, MA_OWNED);
2507 if (p1 == NULL)
2508 return (1);
2509
2510 ISRUN(p1, esta);
2511 ISRUN(p2, estb);
2512
2513 /*
2514 * see if at least one of them is runnable
2515 */
2516 switch (TESTAB(esta, estb)) {
2517 case ONLYA:
2518 return (0);
2519 case ONLYB:
2520 return (1);
2521 case BOTH:
2522 /*
2523 * tie - favor one with highest recent cpu utilization
2524 */
2525 esta = estb = 0;
2526 FOREACH_KSEGRP_IN_PROC(p1,kg) {
2527 esta += kg->kg_estcpu;
2528 }
2529 FOREACH_KSEGRP_IN_PROC(p2,kg) {
2530 estb += kg->kg_estcpu;
2531 }
2532 if (estb > esta)
2533 return (1);
2534 if (esta > estb)
2535 return (0);
2536 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
2537 }
2538 /*
2539 * weed out zombies
2540 */
2541 switch (TESTAB(p1->p_state == PRS_ZOMBIE, p2->p_state == PRS_ZOMBIE)) {
2542 case ONLYA:
2543 return (1);
2544 case ONLYB:
2545 return (0);
2546 case BOTH:
2547 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
2548 }
2549
2550 #if 0 /* XXXKSE */
2551 /*
2552 * pick the one with the smallest sleep time
2553 */
2554 if (p2->p_slptime > p1->p_slptime)
2555 return (0);
2556 if (p1->p_slptime > p2->p_slptime)
2557 return (1);
2558 /*
2559 * favor one sleeping in a non-interruptible sleep
2560 */
2561 if (p1->p_sflag & PS_SINTR && (p2->p_sflag & PS_SINTR) == 0)
2562 return (1);
2563 if (p2->p_sflag & PS_SINTR && (p1->p_sflag & PS_SINTR) == 0)
2564 return (0);
2565 #endif
2566 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
2567 }
2568
2569 /*
2570 * Output char to tty; console putchar style.
2571 */
2572 int
2573 tputchar(int c, struct tty *tp)
2574 {
2575 int s;
2576
2577 s = spltty();
2578 if (!ISSET(tp->t_state, TS_CONNECTED)) {
2579 splx(s);
2580 return (-1);
2581 }
2582 if (c == '\n')
2583 (void)ttyoutput('\r', tp);
2584 (void)ttyoutput(c, tp);
2585 ttstart(tp);
2586 splx(s);
2587 return (0);
2588 }
2589
2590 /*
2591 * Sleep on chan, returning ERESTART if tty changed while we napped and
2592 * returning any errors (e.g. EINTR/EWOULDBLOCK) reported by tsleep. If
2593 * the tty is revoked, restarting a pending call will redo validation done
2594 * at the start of the call.
2595 */
2596 int
2597 ttysleep(struct tty *tp, void *chan, int pri, char *wmesg, int timo)
2598 {
2599 int error;
2600 int gen;
2601
2602 gen = tp->t_gen;
2603 error = tsleep(chan, pri, wmesg, timo);
2604 if (error)
2605 return (error);
2606 return (tp->t_gen == gen ? 0 : ERESTART);
2607 }
2608
2609 /*
2610 * Allocate a tty struct. Clists in the struct will be allocated by
2611 * ttyopen().
2612 */
2613 struct tty *
2614 ttymalloc(struct tty *tp)
2615 {
2616
2617 if (tp)
2618 return(tp);
2619 tp = malloc(sizeof *tp, M_TTYS, M_WAITOK | M_ZERO);
2620 ttyregister(tp);
2621 return (tp);
2622 }
2623
2624 #if 0 /* XXX not yet usable: session leader holds a ref (see kern_exit.c). */
2625 /*
2626 * Free a tty struct. Clists in the struct should have been freed by
2627 * ttyclose().
2628 */
2629 void
2630 ttyfree(struct tty *tp)
2631 {
2632 free(tp, M_TTYS);
2633 }
2634 #endif /* 0 */
2635
2636 void
2637 ttyregister(struct tty *tp)
2638 {
2639 tp->t_timeout = -1;
2640 SLIST_INSERT_HEAD(&tty_list, tp, t_list);
2641 }
2642
2643 static int
2644 sysctl_kern_ttys(SYSCTL_HANDLER_ARGS)
2645 {
2646 struct tty *tp;
2647 struct xtty xt;
2648 int error;
2649
2650 SLIST_FOREACH(tp, &tty_list, t_list) {
2651 bzero(&xt, sizeof xt);
2652 xt.xt_size = sizeof xt;
2653 #define XT_COPY(field) xt.xt_##field = tp->t_##field
2654 xt.xt_rawcc = tp->t_rawq.c_cc;
2655 xt.xt_cancc = tp->t_canq.c_cc;
2656 xt.xt_outcc = tp->t_outq.c_cc;
2657 XT_COPY(line);
2658 if (tp->t_dev)
2659 xt.xt_dev = dev2udev(tp->t_dev);
2660 XT_COPY(state);
2661 XT_COPY(flags);
2662 XT_COPY(timeout);
2663 if (tp->t_pgrp)
2664 xt.xt_pgid = tp->t_pgrp->pg_id;
2665 if (tp->t_session)
2666 xt.xt_sid = tp->t_session->s_sid;
2667 XT_COPY(termios);
2668 XT_COPY(winsize);
2669 XT_COPY(column);
2670 XT_COPY(rocount);
2671 XT_COPY(rocol);
2672 XT_COPY(ififosize);
2673 XT_COPY(ihiwat);
2674 XT_COPY(ilowat);
2675 XT_COPY(ispeedwat);
2676 XT_COPY(ohiwat);
2677 XT_COPY(olowat);
2678 XT_COPY(ospeedwat);
2679 #undef XT_COPY
2680 error = SYSCTL_OUT(req, &xt, sizeof xt);
2681 if (error)
2682 return (error);
2683 }
2684 return (0);
2685 }
2686
2687 SYSCTL_PROC(_kern, OID_AUTO, ttys, CTLTYPE_OPAQUE|CTLFLAG_RD,
2688 0, 0, sysctl_kern_ttys, "S,xtty", "All ttys");
2689 SYSCTL_LONG(_kern, OID_AUTO, tty_nin, CTLFLAG_RD,
2690 &tk_nin, 0, "Total TTY in characters");
2691 SYSCTL_LONG(_kern, OID_AUTO, tty_nout, CTLFLAG_RD,
2692 &tk_nout, 0, "Total TTY out characters");
2693
2694 void
2695 nottystop(struct tty *tp, int rw)
2696 {
2697
2698 return;
2699 }
2700
2701 int
2702 ttyread(dev_t dev, struct uio *uio, int flag)
2703 {
2704 struct tty *tp;
2705
2706 tp = dev->si_tty;
2707 if (tp == NULL)
2708 return (ENODEV);
2709 return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
2710 }
2711
2712 int
2713 ttywrite(dev_t dev, struct uio *uio, int flag)
2714 {
2715 struct tty *tp;
2716
2717 tp = dev->si_tty;
2718 if (tp == NULL)
2719 return (ENODEV);
2720 return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
2721 }
Cache object: dcbcc5967830da08e2ab48414e9f8bdf
|