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