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