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