tty.c revision 1.1.1.2 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 */
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 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 s = spltty(); /* Don't interrupt tabs. */
558 c -= b_to_q(" ", c, &tp->t_outq);
559 tk_nout += c;
560 tp->t_outcc += c;
561 splx(s);
562 }
563 tp->t_column += c;
564 return (c ? -1 : '\t');
565 }
566 if (c == CEOT && ISSET(oflag, ONOEOT))
567 return (-1);
568
569 /*
570 * Newline translation: if ONLCR is set,
571 * translate newline into "\r\n".
572 */
573 if (c == '\n' && ISSET(tp->t_oflag, ONLCR)) {
574 tk_nout++;
575 tp->t_outcc++;
576 if (putc('\r', &tp->t_outq))
577 return (c);
578 }
579 tk_nout++;
580 tp->t_outcc++;
581 if (!ISSET(tp->t_lflag, FLUSHO) && putc(c, &tp->t_outq))
582 return (c);
583
584 col = tp->t_column;
585 switch (CCLASS(c)) {
586 case BACKSPACE:
587 if (col > 0)
588 --col;
589 break;
590 case CONTROL:
591 break;
592 case NEWLINE:
593 case RETURN:
594 col = 0;
595 break;
596 case ORDINARY:
597 ++col;
598 break;
599 case TAB:
600 col = (col + 8) & ~7;
601 break;
602 }
603 tp->t_column = col;
604 return (-1);
605 }
606
607 /*
608 * Ioctls for all tty devices. Called after line-discipline specific ioctl
609 * has been called to do discipline-specific functions and/or reject any
610 * of these ioctl commands.
611 */
612 /* ARGSUSED */
613 int
614 ttioctl(tp, cmd, data, flag)
615 register struct tty *tp;
616 int cmd, flag;
617 void *data;
618 {
619 extern struct tty *constty; /* Temporary virtual console. */
620 extern int nlinesw;
621 register struct proc *p;
622 int s, error;
623
624 p = curproc; /* XXX */
625
626 /* If the ioctl involves modification, hang if in the background. */
627 switch (cmd) {
628 case TIOCFLUSH:
629 case TIOCSETA:
630 case TIOCSETD:
631 case TIOCSETAF:
632 case TIOCSETAW:
633 #ifdef notdef
634 case TIOCSPGRP:
635 #endif
636 case TIOCSTI:
637 case TIOCSWINSZ:
638 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
639 case TIOCLBIC:
640 case TIOCLBIS:
641 case TIOCLSET:
642 case TIOCSETC:
643 case OTIOCSETD:
644 case TIOCSETN:
645 case TIOCSETP:
646 case TIOCSLTC:
647 #endif
648 while (isbackground(curproc, tp) &&
649 p->p_pgrp->pg_jobc && (p->p_flag & P_PPWAIT) == 0 &&
650 (p->p_sigignore & sigmask(SIGTTOU)) == 0 &&
651 (p->p_sigmask & sigmask(SIGTTOU)) == 0) {
652 pgsignal(p->p_pgrp, SIGTTOU, 1);
653 if (error = ttysleep(tp,
654 &lbolt, TTOPRI | PCATCH, ttybg, 0))
655 return (error);
656 }
657 break;
658 }
659
660 switch (cmd) { /* Process the ioctl. */
661 case FIOASYNC: /* set/clear async i/o */
662 s = spltty();
663 if (*(int *)data)
664 SET(tp->t_state, TS_ASYNC);
665 else
666 CLR(tp->t_state, TS_ASYNC);
667 splx(s);
668 break;
669 case FIONBIO: /* set/clear non-blocking i/o */
670 break; /* XXX: delete. */
671 case FIONREAD: /* get # bytes to read */
672 *(int *)data = ttnread(tp);
673 break;
674 case TIOCEXCL: /* set exclusive use of tty */
675 s = spltty();
676 SET(tp->t_state, TS_XCLUDE);
677 splx(s);
678 break;
679 case TIOCFLUSH: { /* flush buffers */
680 register int flags = *(int *)data;
681
682 if (flags == 0)
683 flags = FREAD | FWRITE;
684 else
685 flags &= FREAD | FWRITE;
686 ttyflush(tp, flags);
687 break;
688 }
689 case TIOCCONS: /* become virtual console */
690 if (*(int *)data) {
691 if (constty && constty != tp &&
692 ISSET(constty->t_state, TS_CARR_ON | TS_ISOPEN) ==
693 (TS_CARR_ON | TS_ISOPEN))
694 return (EBUSY);
695 #ifndef UCONSOLE
696 if (error = suser(p->p_ucred, &p->p_acflag))
697 return (error);
698 #endif
699 constty = tp;
700 } else if (tp == constty)
701 constty = NULL;
702 break;
703 case TIOCDRAIN: /* wait till output drained */
704 if (error = ttywait(tp))
705 return (error);
706 break;
707 case TIOCGETA: { /* get termios struct */
708 struct termios *t = (struct termios *)data;
709
710 bcopy(&tp->t_termios, t, sizeof(struct termios));
711 break;
712 }
713 case TIOCGETD: /* get line discipline */
714 *(int *)data = tp->t_line;
715 break;
716 case TIOCGWINSZ: /* get window size */
717 *(struct winsize *)data = tp->t_winsize;
718 break;
719 case TIOCGPGRP: /* get pgrp of tty */
720 if (!isctty(p, tp))
721 return (ENOTTY);
722 *(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
723 break;
724 #ifdef TIOCHPCL
725 case TIOCHPCL: /* hang up on last close */
726 s = spltty();
727 SET(tp->t_cflag, HUPCL);
728 splx(s);
729 break;
730 #endif
731 case TIOCNXCL: /* reset exclusive use of tty */
732 s = spltty();
733 CLR(tp->t_state, TS_XCLUDE);
734 splx(s);
735 break;
736 case TIOCOUTQ: /* output queue size */
737 *(int *)data = tp->t_outq.c_cc;
738 break;
739 case TIOCSETA: /* set termios struct */
740 case TIOCSETAW: /* drain output, set */
741 case TIOCSETAF: { /* drn out, fls in, set */
742 register struct termios *t = (struct termios *)data;
743
744 s = spltty();
745 if (cmd == TIOCSETAW || cmd == TIOCSETAF) {
746 if (error = ttywait(tp)) {
747 splx(s);
748 return (error);
749 }
750 if (cmd == TIOCSETAF)
751 ttyflush(tp, FREAD);
752 }
753 if (!ISSET(t->c_cflag, CIGNORE)) {
754 /*
755 * Set device hardware.
756 */
757 if (tp->t_param && (error = (*tp->t_param)(tp, t))) {
758 splx(s);
759 return (error);
760 } else {
761 if (!ISSET(tp->t_state, TS_CARR_ON) &&
762 ISSET(tp->t_cflag, CLOCAL) &&
763 !ISSET(t->c_cflag, CLOCAL)) {
764 CLR(tp->t_state, TS_ISOPEN);
765 SET(tp->t_state, TS_WOPEN);
766 ttwakeup(tp);
767 }
768 tp->t_cflag = t->c_cflag;
769 tp->t_ispeed = t->c_ispeed;
770 tp->t_ospeed = t->c_ospeed;
771 }
772 ttsetwater(tp);
773 }
774 if (cmd != TIOCSETAF) {
775 if (ISSET(t->c_lflag, ICANON) !=
776 ISSET(tp->t_lflag, ICANON))
777 if (ISSET(t->c_lflag, ICANON)) {
778 SET(tp->t_lflag, PENDIN);
779 ttwakeup(tp);
780 } else {
781 struct clist tq;
782
783 catq(&tp->t_rawq, &tp->t_canq);
784 tq = tp->t_rawq;
785 tp->t_rawq = tp->t_canq;
786 tp->t_canq = tq;
787 CLR(tp->t_lflag, PENDIN);
788 }
789 }
790 tp->t_iflag = t->c_iflag;
791 tp->t_oflag = t->c_oflag;
792 /*
793 * Make the EXTPROC bit read only.
794 */
795 if (ISSET(tp->t_lflag, EXTPROC))
796 SET(t->c_lflag, EXTPROC);
797 else
798 CLR(t->c_lflag, EXTPROC);
799 tp->t_lflag = t->c_lflag | ISSET(tp->t_lflag, PENDIN);
800 bcopy(t->c_cc, tp->t_cc, sizeof(t->c_cc));
801 splx(s);
802 break;
803 }
804 case TIOCSETD: { /* set line discipline */
805 register int t = *(int *)data;
806 dev_t device = tp->t_dev;
807
808 if ((u_int)t >= nlinesw)
809 return (ENXIO);
810 if (t != tp->t_line) {
811 s = spltty();
812 (*linesw[tp->t_line].l_close)(tp, flag);
813 error = (*linesw[t].l_open)(device, tp);
814 if (error) {
815 (void)(*linesw[tp->t_line].l_open)(device, tp);
816 splx(s);
817 return (error);
818 }
819 tp->t_line = t;
820 splx(s);
821 }
822 break;
823 }
824 case TIOCSTART: /* start output, like ^Q */
825 s = spltty();
826 if (ISSET(tp->t_state, TS_TTSTOP) ||
827 ISSET(tp->t_lflag, FLUSHO)) {
828 CLR(tp->t_lflag, FLUSHO);
829 CLR(tp->t_state, TS_TTSTOP);
830 ttstart(tp);
831 }
832 splx(s);
833 break;
834 case TIOCSTI: /* simulate terminal input */
835 if (p->p_ucred->cr_uid && (flag & FREAD) == 0)
836 return (EPERM);
837 if (p->p_ucred->cr_uid && !isctty(p, tp))
838 return (EACCES);
839 (*linesw[tp->t_line].l_rint)(*(u_char *)data, tp);
840 break;
841 case TIOCSTOP: /* stop output, like ^S */
842 s = spltty();
843 if (!ISSET(tp->t_state, TS_TTSTOP)) {
844 SET(tp->t_state, TS_TTSTOP);
845 #ifdef sun4c /* XXX */
846 (*tp->t_stop)(tp, 0);
847 #else
848 (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
849 #endif
850 }
851 splx(s);
852 break;
853 case TIOCSCTTY: /* become controlling tty */
854 /* Session ctty vnode pointer set in vnode layer. */
855 if (!SESS_LEADER(p) ||
856 (p->p_session->s_ttyvp || tp->t_session) &&
857 (tp->t_session != p->p_session))
858 return (EPERM);
859 tp->t_session = p->p_session;
860 tp->t_pgrp = p->p_pgrp;
861 p->p_session->s_ttyp = tp;
862 p->p_flag |= P_CONTROLT;
863 break;
864 case TIOCSPGRP: { /* set pgrp of tty */
865 register struct pgrp *pgrp = pgfind(*(int *)data);
866
867 if (!isctty(p, tp))
868 return (ENOTTY);
869 else if (pgrp == NULL || pgrp->pg_session != p->p_session)
870 return (EPERM);
871 tp->t_pgrp = pgrp;
872 break;
873 }
874 case TIOCSWINSZ: /* set window size */
875 if (bcmp((caddr_t)&tp->t_winsize, data,
876 sizeof (struct winsize))) {
877 tp->t_winsize = *(struct winsize *)data;
878 pgsignal(tp->t_pgrp, SIGWINCH, 1);
879 }
880 break;
881 default:
882 #if defined(COMPAT_43) || defined(COMPAT_SUNOS)
883 return (ttcompat(tp, cmd, data, flag));
884 #else
885 return (-1);
886 #endif
887 }
888 return (0);
889 }
890
891 int
892 ttselect(device, rw, p)
893 dev_t device;
894 int rw;
895 struct proc *p;
896 {
897 register struct tty *tp;
898 int nread, s;
899
900 tp = &cdevsw[major(device)].d_ttys[minor(device)];
901
902 s = spltty();
903 switch (rw) {
904 case FREAD:
905 nread = ttnread(tp);
906 if (nread > 0 || !ISSET(tp->t_cflag, CLOCAL) &&
907 !ISSET(tp->t_state, TS_CARR_ON))
908 goto win;
909 selrecord(p, &tp->t_rsel);
910 break;
911 case FWRITE:
912 if (tp->t_outq.c_cc <= tp->t_lowat) {
913 win: splx(s);
914 return (1);
915 }
916 selrecord(p, &tp->t_wsel);
917 break;
918 }
919 splx(s);
920 return (0);
921 }
922
923 static int
924 ttnread(tp)
925 struct tty *tp;
926 {
927 int nread;
928
929 if (ISSET(tp->t_lflag, PENDIN))
930 ttypend(tp);
931 nread = tp->t_canq.c_cc;
932 if (!ISSET(tp->t_lflag, ICANON))
933 nread += tp->t_rawq.c_cc;
934 return (nread);
935 }
936
937 /*
938 * Wait for output to drain.
939 */
940 int
941 ttywait(tp)
942 register struct tty *tp;
943 {
944 int error, s;
945
946 error = 0;
947 s = spltty();
948 while ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
949 (ISSET(tp->t_state, TS_CARR_ON) || ISSET(tp->t_cflag, CLOCAL))
950 && tp->t_oproc) {
951 (*tp->t_oproc)(tp);
952 SET(tp->t_state, TS_ASLEEP);
953 if (error = ttysleep(tp,
954 &tp->t_outq, TTOPRI | PCATCH, ttyout, 0))
955 break;
956 }
957 splx(s);
958 return (error);
959 }
960
961 /*
962 * Flush if successfully wait.
963 */
964 int
965 ttywflush(tp)
966 struct tty *tp;
967 {
968 int error;
969
970 if ((error = ttywait(tp)) == 0)
971 ttyflush(tp, FREAD);
972 return (error);
973 }
974
975 /*
976 * Flush tty read and/or write queues, notifying anyone waiting.
977 */
978 void
979 ttyflush(tp, rw)
980 register struct tty *tp;
981 int rw;
982 {
983 register int s;
984
985 s = spltty();
986 if (rw & FREAD) {
987 FLUSHQ(&tp->t_canq);
988 FLUSHQ(&tp->t_rawq);
989 tp->t_rocount = 0;
990 tp->t_rocol = 0;
991 CLR(tp->t_state, TS_LOCAL);
992 ttwakeup(tp);
993 }
994 if (rw & FWRITE) {
995 CLR(tp->t_state, TS_TTSTOP);
996 #ifdef sun4c /* XXX */
997 (*tp->t_stop)(tp, rw);
998 #else
999 (*cdevsw[major(tp->t_dev)].d_stop)(tp, rw);
1000 #endif
1001 FLUSHQ(&tp->t_outq);
1002 wakeup((caddr_t)&tp->t_outq);
1003 selwakeup(&tp->t_wsel);
1004 }
1005 splx(s);
1006 }
1007
1008 /*
1009 * Copy in the default termios characters.
1010 */
1011 void
1012 ttychars(tp)
1013 struct tty *tp;
1014 {
1015
1016 bcopy(ttydefchars, tp->t_cc, sizeof(ttydefchars));
1017 }
1018
1019 /*
1020 * Send stop character on input overflow.
1021 */
1022 static void
1023 ttyblock(tp)
1024 register struct tty *tp;
1025 {
1026 register int total;
1027
1028 total = tp->t_rawq.c_cc + tp->t_canq.c_cc;
1029 if (tp->t_rawq.c_cc > TTYHOG) {
1030 ttyflush(tp, FREAD | FWRITE);
1031 CLR(tp->t_state, TS_TBLOCK);
1032 }
1033 /*
1034 * Block further input iff: current input > threshold
1035 * AND input is available to user program.
1036 */
1037 if (total >= TTYHOG / 2 &&
1038 !ISSET(tp->t_state, TS_TBLOCK) &&
1039 !ISSET(tp->t_lflag, ICANON) || tp->t_canq.c_cc > 0 &&
1040 tp->t_cc[VSTOP] != _POSIX_VDISABLE) {
1041 if (putc(tp->t_cc[VSTOP], &tp->t_outq) == 0) {
1042 SET(tp->t_state, TS_TBLOCK);
1043 ttstart(tp);
1044 }
1045 }
1046 }
1047
1048 void
1049 ttrstrt(tp_arg)
1050 void *tp_arg;
1051 {
1052 struct tty *tp;
1053 int s;
1054
1055 #ifdef DIAGNOSTIC
1056 if (tp_arg == NULL)
1057 panic("ttrstrt");
1058 #endif
1059 tp = tp_arg;
1060 s = spltty();
1061
1062 CLR(tp->t_state, TS_TIMEOUT);
1063 ttstart(tp);
1064
1065 splx(s);
1066 }
1067
1068 int
1069 ttstart(tp)
1070 struct tty *tp;
1071 {
1072
1073 if (tp->t_oproc != NULL) /* XXX: Kludge for pty. */
1074 (*tp->t_oproc)(tp);
1075 return (0);
1076 }
1077
1078 /*
1079 * "close" a line discipline
1080 */
1081 int
1082 ttylclose(tp, flag)
1083 struct tty *tp;
1084 int flag;
1085 {
1086
1087 if (flag & IO_NDELAY)
1088 ttyflush(tp, FREAD | FWRITE);
1089 else
1090 ttywflush(tp);
1091 return (0);
1092 }
1093
1094 /*
1095 * Handle modem control transition on a tty.
1096 * Flag indicates new state of carrier.
1097 * Returns 0 if the line should be turned off, otherwise 1.
1098 */
1099 int
1100 ttymodem(tp, flag)
1101 register struct tty *tp;
1102 int flag;
1103 {
1104
1105 if (!ISSET(tp->t_state, TS_WOPEN) && ISSET(tp->t_cflag, MDMBUF)) {
1106 /*
1107 * MDMBUF: do flow control according to carrier flag
1108 */
1109 if (flag) {
1110 CLR(tp->t_state, TS_TTSTOP);
1111 ttstart(tp);
1112 } else if (!ISSET(tp->t_state, TS_TTSTOP)) {
1113 SET(tp->t_state, TS_TTSTOP);
1114 #ifdef sun4c /* XXX */
1115 (*tp->t_stop)(tp, 0);
1116 #else
1117 (*cdevsw[major(tp->t_dev)].d_stop)(tp, 0);
1118 #endif
1119 }
1120 } else if (flag == 0) {
1121 /*
1122 * Lost carrier.
1123 */
1124 CLR(tp->t_state, TS_CARR_ON);
1125 if (ISSET(tp->t_state, TS_ISOPEN) &&
1126 !ISSET(tp->t_cflag, CLOCAL)) {
1127 if (tp->t_session && tp->t_session->s_leader)
1128 psignal(tp->t_session->s_leader, SIGHUP);
1129 ttyflush(tp, FREAD | FWRITE);
1130 return (0);
1131 }
1132 } else {
1133 /*
1134 * Carrier now on.
1135 */
1136 SET(tp->t_state, TS_CARR_ON);
1137 ttwakeup(tp);
1138 }
1139 return (1);
1140 }
1141
1142 /*
1143 * Default modem control routine (for other line disciplines).
1144 * Return argument flag, to turn off device on carrier drop.
1145 */
1146 int
1147 nullmodem(tp, flag)
1148 register struct tty *tp;
1149 int flag;
1150 {
1151
1152 if (flag)
1153 SET(tp->t_state, TS_CARR_ON);
1154 else {
1155 CLR(tp->t_state, TS_CARR_ON);
1156 if (!ISSET(tp->t_cflag, CLOCAL)) {
1157 if (tp->t_session && tp->t_session->s_leader)
1158 psignal(tp->t_session->s_leader, SIGHUP);
1159 return (0);
1160 }
1161 }
1162 return (1);
1163 }
1164
1165 /*
1166 * Reinput pending characters after state switch
1167 * call at spltty().
1168 */
1169 void
1170 ttypend(tp)
1171 register struct tty *tp;
1172 {
1173 struct clist tq;
1174 register c;
1175
1176 CLR(tp->t_lflag, PENDIN);
1177 SET(tp->t_state, TS_TYPEN);
1178 tq = tp->t_rawq;
1179 tp->t_rawq.c_cc = 0;
1180 tp->t_rawq.c_cf = tp->t_rawq.c_cl = 0;
1181 while ((c = getc(&tq)) >= 0)
1182 ttyinput(c, tp);
1183 CLR(tp->t_state, TS_TYPEN);
1184 }
1185
1186 /*
1187 * Process a read call on a tty device.
1188 */
1189 int
1190 ttread(tp, uio, flag)
1191 register struct tty *tp;
1192 struct uio *uio;
1193 int flag;
1194 {
1195 register struct clist *qp;
1196 register int c;
1197 register long lflag;
1198 register u_char *cc = tp->t_cc;
1199 register struct proc *p = curproc;
1200 int s, first, error = 0;
1201
1202 loop: lflag = tp->t_lflag;
1203 s = spltty();
1204 /*
1205 * take pending input first
1206 */
1207 if (ISSET(lflag, PENDIN))
1208 ttypend(tp);
1209 splx(s);
1210
1211 /*
1212 * Hang process if it's in the background.
1213 */
1214 if (isbackground(p, tp)) {
1215 if ((p->p_sigignore & sigmask(SIGTTIN)) ||
1216 (p->p_sigmask & sigmask(SIGTTIN)) ||
1217 p->p_flag & P_PPWAIT || p->p_pgrp->pg_jobc == 0)
1218 return (EIO);
1219 pgsignal(p->p_pgrp, SIGTTIN, 1);
1220 if (error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, ttybg, 0))
1221 return (error);
1222 goto loop;
1223 }
1224
1225 /*
1226 * If canonical, use the canonical queue,
1227 * else use the raw queue.
1228 *
1229 * (should get rid of clists...)
1230 */
1231 qp = ISSET(lflag, ICANON) ? &tp->t_canq : &tp->t_rawq;
1232
1233 /*
1234 * If there is no input, sleep on rawq
1235 * awaiting hardware receipt and notification.
1236 * If we have data, we don't need to check for carrier.
1237 */
1238 s = spltty();
1239 if (qp->c_cc <= 0) {
1240 int carrier;
1241
1242 carrier = ISSET(tp->t_state, TS_CARR_ON) ||
1243 ISSET(tp->t_cflag, CLOCAL);
1244 if (!carrier && ISSET(tp->t_state, TS_ISOPEN)) {
1245 splx(s);
1246 return (0); /* EOF */
1247 }
1248 if (flag & IO_NDELAY) {
1249 splx(s);
1250 return (EWOULDBLOCK);
1251 }
1252 error = ttysleep(tp, &tp->t_rawq, TTIPRI | PCATCH,
1253 carrier ? ttyin : ttopen, 0);
1254 splx(s);
1255 if (error)
1256 return (error);
1257 goto loop;
1258 }
1259 splx(s);
1260
1261 /*
1262 * Input present, check for input mapping and processing.
1263 */
1264 first = 1;
1265 while ((c = getc(qp)) >= 0) {
1266 /*
1267 * delayed suspend (^Y)
1268 */
1269 if (CCEQ(cc[VDSUSP], c) && ISSET(lflag, ISIG)) {
1270 pgsignal(tp->t_pgrp, SIGTSTP, 1);
1271 if (first) {
1272 if (error = ttysleep(tp,
1273 &lbolt, TTIPRI | PCATCH, ttybg, 0))
1274 break;
1275 goto loop;
1276 }
1277 break;
1278 }
1279 /*
1280 * Interpret EOF only in canonical mode.
1281 */
1282 if (CCEQ(cc[VEOF], c) && ISSET(lflag, ICANON))
1283 break;
1284 /*
1285 * Give user character.
1286 */
1287 error = ureadc(c, uio);
1288 if (error)
1289 break;
1290 if (uio->uio_resid == 0)
1291 break;
1292 /*
1293 * In canonical mode check for a "break character"
1294 * marking the end of a "line of input".
1295 */
1296 if (ISSET(lflag, ICANON) && TTBREAKC(c))
1297 break;
1298 first = 0;
1299 }
1300 /*
1301 * Look to unblock output now that (presumably)
1302 * the input queue has gone down.
1303 */
1304 s = spltty();
1305 if (ISSET(tp->t_state, TS_TBLOCK) && tp->t_rawq.c_cc < TTYHOG/5) {
1306 if (cc[VSTART] != _POSIX_VDISABLE &&
1307 putc(cc[VSTART], &tp->t_outq) == 0) {
1308 CLR(tp->t_state, TS_TBLOCK);
1309 ttstart(tp);
1310 }
1311 }
1312 splx(s);
1313 return (error);
1314 }
1315
1316 /*
1317 * Check the output queue on tp for space for a kernel message (from uprintf
1318 * or tprintf). Allow some space over the normal hiwater mark so we don't
1319 * lose messages due to normal flow control, but don't let the tty run amok.
1320 * Sleeps here are not interruptible, but we return prematurely if new signals
1321 * arrive.
1322 */
1323 int
1324 ttycheckoutq(tp, wait)
1325 register struct tty *tp;
1326 int wait;
1327 {
1328 int hiwat, s, oldsig;
1329
1330 hiwat = tp->t_hiwat;
1331 s = spltty();
1332 oldsig = wait ? curproc->p_siglist : 0;
1333 if (tp->t_outq.c_cc > hiwat + 200)
1334 while (tp->t_outq.c_cc > hiwat) {
1335 ttstart(tp);
1336 if (wait == 0 || curproc->p_siglist != oldsig) {
1337 splx(s);
1338 return (0);
1339 }
1340 timeout((void (*)__P((void *)))wakeup,
1341 (void *)&tp->t_outq, hz);
1342 SET(tp->t_state, TS_ASLEEP);
1343 sleep((caddr_t)&tp->t_outq, PZERO - 1);
1344 }
1345 splx(s);
1346 return (1);
1347 }
1348
1349 /*
1350 * Process a write call on a tty device.
1351 */
1352 int
1353 ttwrite(tp, uio, flag)
1354 register struct tty *tp;
1355 register struct uio *uio;
1356 int flag;
1357 {
1358 register char *cp;
1359 register int cc, ce;
1360 register struct proc *p;
1361 int i, hiwat, cnt, error, s;
1362 char obuf[OBUFSIZ];
1363
1364 hiwat = tp->t_hiwat;
1365 cnt = uio->uio_resid;
1366 error = 0;
1367 cc = 0;
1368 loop:
1369 s = spltty();
1370 if (!ISSET(tp->t_state, TS_CARR_ON) &&
1371 !ISSET(tp->t_cflag, CLOCAL)) {
1372 if (ISSET(tp->t_state, TS_ISOPEN)) {
1373 splx(s);
1374 return (EIO);
1375 } else if (flag & IO_NDELAY) {
1376 splx(s);
1377 error = EWOULDBLOCK;
1378 goto out;
1379 } else {
1380 /* Sleep awaiting carrier. */
1381 error = ttysleep(tp,
1382 &tp->t_rawq, TTIPRI | PCATCH,ttopen, 0);
1383 splx(s);
1384 if (error)
1385 goto out;
1386 goto loop;
1387 }
1388 }
1389 splx(s);
1390 /*
1391 * Hang the process if it's in the background.
1392 */
1393 p = curproc;
1394 if (isbackground(p, tp) &&
1395 ISSET(tp->t_lflag, TOSTOP) && (p->p_flag & P_PPWAIT) == 0 &&
1396 (p->p_sigignore & sigmask(SIGTTOU)) == 0 &&
1397 (p->p_sigmask & sigmask(SIGTTOU)) == 0 &&
1398 p->p_pgrp->pg_jobc) {
1399 pgsignal(p->p_pgrp, SIGTTOU, 1);
1400 if (error = ttysleep(tp, &lbolt, TTIPRI | PCATCH, ttybg, 0))
1401 goto out;
1402 goto loop;
1403 }
1404 /*
1405 * Process the user's data in at most OBUFSIZ chunks. Perform any
1406 * output translation. Keep track of high water mark, sleep on
1407 * overflow awaiting device aid in acquiring new space.
1408 */
1409 while (uio->uio_resid > 0 || cc > 0) {
1410 if (ISSET(tp->t_lflag, FLUSHO)) {
1411 uio->uio_resid = 0;
1412 return (0);
1413 }
1414 if (tp->t_outq.c_cc > hiwat)
1415 goto ovhiwat;
1416 /*
1417 * Grab a hunk of data from the user, unless we have some
1418 * leftover from last time.
1419 */
1420 if (cc == 0) {
1421 cc = min(uio->uio_resid, OBUFSIZ);
1422 cp = obuf;
1423 error = uiomove(cp, cc, uio);
1424 if (error) {
1425 cc = 0;
1426 break;
1427 }
1428 }
1429 /*
1430 * If nothing fancy need be done, grab those characters we
1431 * can handle without any of ttyoutput's processing and
1432 * just transfer them to the output q. For those chars
1433 * which require special processing (as indicated by the
1434 * bits in char_type), call ttyoutput. After processing
1435 * a hunk of data, look for FLUSHO so ^O's will take effect
1436 * immediately.
1437 */
1438 while (cc > 0) {
1439 if (!ISSET(tp->t_oflag, OPOST))
1440 ce = cc;
1441 else {
1442 ce = cc - scanc((u_int)cc, (u_char *)cp,
1443 (u_char *)char_type, CCLASSMASK);
1444 /*
1445 * If ce is zero, then we're processing
1446 * a special character through ttyoutput.
1447 */
1448 if (ce == 0) {
1449 tp->t_rocount = 0;
1450 if (ttyoutput(*cp, tp) >= 0) {
1451 /* No Clists, wait a bit. */
1452 ttstart(tp);
1453 if (error = ttysleep(tp, &lbolt,
1454 TTOPRI | PCATCH, ttybuf, 0))
1455 break;
1456 goto loop;
1457 }
1458 cp++;
1459 cc--;
1460 if (ISSET(tp->t_lflag, FLUSHO) ||
1461 tp->t_outq.c_cc > hiwat)
1462 goto ovhiwat;
1463 continue;
1464 }
1465 }
1466 /*
1467 * A bunch of normal characters have been found.
1468 * Transfer them en masse to the output queue and
1469 * continue processing at the top of the loop.
1470 * If there are any further characters in this
1471 * <= OBUFSIZ chunk, the first should be a character
1472 * requiring special handling by ttyoutput.
1473 */
1474 tp->t_rocount = 0;
1475 i = b_to_q(cp, ce, &tp->t_outq);
1476 ce -= i;
1477 tp->t_column += ce;
1478 cp += ce, cc -= ce, tk_nout += ce;
1479 tp->t_outcc += ce;
1480 if (i > 0) {
1481 /* No Clists, wait a bit. */
1482 ttstart(tp);
1483 if (error = ttysleep(tp,
1484 &lbolt, TTOPRI | PCATCH, ttybuf, 0))
1485 break;
1486 goto loop;
1487 }
1488 if (ISSET(tp->t_lflag, FLUSHO) ||
1489 tp->t_outq.c_cc > hiwat)
1490 break;
1491 }
1492 ttstart(tp);
1493 }
1494 out:
1495 /*
1496 * If cc is nonzero, we leave the uio structure inconsistent, as the
1497 * offset and iov pointers have moved forward, but it doesn't matter
1498 * (the call will either return short or restart with a new uio).
1499 */
1500 uio->uio_resid += cc;
1501 return (error);
1502
1503 ovhiwat:
1504 ttstart(tp);
1505 s = spltty();
1506 /*
1507 * This can only occur if FLUSHO is set in t_lflag,
1508 * or if ttstart/oproc is synchronous (or very fast).
1509 */
1510 if (tp->t_outq.c_cc <= hiwat) {
1511 splx(s);
1512 goto loop;
1513 }
1514 if (flag & IO_NDELAY) {
1515 splx(s);
1516 uio->uio_resid += cc;
1517 return (uio->uio_resid == cnt ? EWOULDBLOCK : 0);
1518 }
1519 SET(tp->t_state, TS_ASLEEP);
1520 error = ttysleep(tp, &tp->t_outq, TTOPRI | PCATCH, ttyout, 0);
1521 splx(s);
1522 if (error)
1523 goto out;
1524 goto loop;
1525 }
1526
1527 /*
1528 * Rubout one character from the rawq of tp
1529 * as cleanly as possible.
1530 */
1531 void
1532 ttyrub(c, tp)
1533 register int c;
1534 register struct tty *tp;
1535 {
1536 register char *cp;
1537 register int savecol;
1538 int tabc, s;
1539
1540 if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC))
1541 return;
1542 CLR(tp->t_lflag, FLUSHO);
1543 if (ISSET(tp->t_lflag, ECHOE)) {
1544 if (tp->t_rocount == 0) {
1545 /*
1546 * Screwed by ttwrite; retype
1547 */
1548 ttyretype(tp);
1549 return;
1550 }
1551 if (c == ('\t' | TTY_QUOTE) || c == ('\n' | TTY_QUOTE))
1552 ttyrubo(tp, 2);
1553 else {
1554 CLR(c, ~TTY_CHARMASK);
1555 switch (CCLASS(c)) {
1556 case ORDINARY:
1557 ttyrubo(tp, 1);
1558 break;
1559 case BACKSPACE:
1560 case CONTROL:
1561 case NEWLINE:
1562 case RETURN:
1563 case VTAB:
1564 if (ISSET(tp->t_lflag, ECHOCTL))
1565 ttyrubo(tp, 2);
1566 break;
1567 case TAB:
1568 if (tp->t_rocount < tp->t_rawq.c_cc) {
1569 ttyretype(tp);
1570 return;
1571 }
1572 s = spltty();
1573 savecol = tp->t_column;
1574 SET(tp->t_state, TS_CNTTB);
1575 SET(tp->t_lflag, FLUSHO);
1576 tp->t_column = tp->t_rocol;
1577 cp = tp->t_rawq.c_cf;
1578 if (cp)
1579 tabc = *cp; /* XXX FIX NEXTC */
1580 for (; cp; cp = nextc(&tp->t_rawq, cp, &tabc))
1581 ttyecho(tabc, tp);
1582 CLR(tp->t_lflag, FLUSHO);
1583 CLR(tp->t_state, TS_CNTTB);
1584 splx(s);
1585
1586 /* savecol will now be length of the tab. */
1587 savecol -= tp->t_column;
1588 tp->t_column += savecol;
1589 if (savecol > 8)
1590 savecol = 8; /* overflow screw */
1591 while (--savecol >= 0)
1592 (void)ttyoutput('\b', tp);
1593 break;
1594 default: /* XXX */
1595 #define PANICSTR "ttyrub: would panic c = %d, val = %d\n"
1596 (void)printf(PANICSTR, c, CCLASS(c));
1597 #ifdef notdef
1598 panic(PANICSTR, c, CCLASS(c));
1599 #endif
1600 }
1601 }
1602 } else if (ISSET(tp->t_lflag, ECHOPRT)) {
1603 if (!ISSET(tp->t_state, TS_ERASE)) {
1604 SET(tp->t_state, TS_ERASE);
1605 (void)ttyoutput('\\', tp);
1606 }
1607 ttyecho(c, tp);
1608 } else
1609 ttyecho(tp->t_cc[VERASE], tp);
1610 --tp->t_rocount;
1611 }
1612
1613 /*
1614 * Back over cnt characters, erasing them.
1615 */
1616 static void
1617 ttyrubo(tp, cnt)
1618 register struct tty *tp;
1619 int cnt;
1620 {
1621
1622 while (cnt-- > 0) {
1623 (void)ttyoutput('\b', tp);
1624 (void)ttyoutput(' ', tp);
1625 (void)ttyoutput('\b', tp);
1626 }
1627 }
1628
1629 /*
1630 * ttyretype --
1631 * Reprint the rawq line. Note, it is assumed that c_cc has already
1632 * been checked.
1633 */
1634 void
1635 ttyretype(tp)
1636 register struct tty *tp;
1637 {
1638 register char *cp;
1639 int s, c;
1640
1641 /* Echo the reprint character. */
1642 if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE)
1643 ttyecho(tp->t_cc[VREPRINT], tp);
1644
1645 (void)ttyoutput('\n', tp);
1646
1647 /*
1648 * XXX
1649 * FIX: NEXTC IS BROKEN - DOESN'T CHECK QUOTE
1650 * BIT OF FIRST CHAR.
1651 */
1652 s = spltty();
1653 for (cp = tp->t_canq.c_cf, c = (cp != NULL ? *cp : 0);
1654 cp != NULL; cp = nextc(&tp->t_canq, cp, &c))
1655 ttyecho(c, tp);
1656 for (cp = tp->t_rawq.c_cf, c = (cp != NULL ? *cp : 0);
1657 cp != NULL; cp = nextc(&tp->t_rawq, cp, &c))
1658 ttyecho(c, tp);
1659 CLR(tp->t_state, TS_ERASE);
1660 splx(s);
1661
1662 tp->t_rocount = tp->t_rawq.c_cc;
1663 tp->t_rocol = 0;
1664 }
1665
1666 /*
1667 * Echo a typed character to the terminal.
1668 */
1669 static void
1670 ttyecho(c, tp)
1671 register int c;
1672 register struct tty *tp;
1673 {
1674
1675 if (!ISSET(tp->t_state, TS_CNTTB))
1676 CLR(tp->t_lflag, FLUSHO);
1677 if ((!ISSET(tp->t_lflag, ECHO) &&
1678 (!ISSET(tp->t_lflag, ECHONL) || c == '\n')) ||
1679 ISSET(tp->t_lflag, EXTPROC))
1680 return;
1681 if (ISSET(tp->t_lflag, ECHOCTL) &&
1682 (ISSET(c, TTY_CHARMASK) <= 037 && c != '\t' && c != '\n' ||
1683 ISSET(c, TTY_CHARMASK) == 0177)) {
1684 (void)ttyoutput('^', tp);
1685 CLR(c, ~TTY_CHARMASK);
1686 if (c == 0177)
1687 c = '?';
1688 else
1689 c += 'A' - 1;
1690 }
1691 (void)ttyoutput(c, tp);
1692 }
1693
1694 /*
1695 * Wake up any readers on a tty.
1696 */
1697 void
1698 ttwakeup(tp)
1699 register struct tty *tp;
1700 {
1701
1702 selwakeup(&tp->t_rsel);
1703 if (ISSET(tp->t_state, TS_ASYNC))
1704 pgsignal(tp->t_pgrp, SIGIO, 1);
1705 wakeup((caddr_t)&tp->t_rawq);
1706 }
1707
1708 /*
1709 * Look up a code for a specified speed in a conversion table;
1710 * used by drivers to map software speed values to hardware parameters.
1711 */
1712 int
1713 ttspeedtab(speed, table)
1714 int speed;
1715 register struct speedtab *table;
1716 {
1717
1718 for ( ; table->sp_speed != -1; table++)
1719 if (table->sp_speed == speed)
1720 return (table->sp_code);
1721 return (-1);
1722 }
1723
1724 /*
1725 * Set tty hi and low water marks.
1726 *
1727 * Try to arrange the dynamics so there's about one second
1728 * from hi to low water.
1729 *
1730 */
1731 void
1732 ttsetwater(tp)
1733 struct tty *tp;
1734 {
1735 register int cps, x;
1736
1737 #define CLAMP(x, h, l) ((x) > h ? h : ((x) < l) ? l : (x))
1738
1739 cps = tp->t_ospeed / 10;
1740 tp->t_lowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT);
1741 x += cps;
1742 x = CLAMP(x, TTMAXHIWAT, TTMINHIWAT);
1743 tp->t_hiwat = roundup(x, CBSIZE);
1744 #undef CLAMP
1745 }
1746
1747 /*
1748 * Report on state of foreground process group.
1749 */
1750 void
1751 ttyinfo(tp)
1752 register struct tty *tp;
1753 {
1754 register struct proc *p, *pick;
1755 struct timeval utime, stime;
1756 int tmp;
1757
1758 if (ttycheckoutq(tp,0) == 0)
1759 return;
1760
1761 /* Print load average. */
1762 tmp = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT;
1763 ttyprintf(tp, "load: %d.%02d ", tmp / 100, tmp % 100);
1764
1765 if (tp->t_session == NULL)
1766 ttyprintf(tp, "not a controlling terminal\n");
1767 else if (tp->t_pgrp == NULL)
1768 ttyprintf(tp, "no foreground process group\n");
1769 else if ((p = tp->t_pgrp->pg_mem) == NULL)
1770 ttyprintf(tp, "empty foreground process group\n");
1771 else {
1772 /* Pick interesting process. */
1773 for (pick = NULL; p != NULL; p = p->p_pgrpnxt)
1774 if (proc_compare(pick, p))
1775 pick = p;
1776
1777 ttyprintf(tp, " cmd: %s %d [%s] ", pick->p_comm, pick->p_pid,
1778 pick->p_stat == SRUN ? "running" :
1779 pick->p_wmesg ? pick->p_wmesg : "iowait");
1780
1781 calcru(pick, &utime, &stime, NULL);
1782
1783 /* Print user time. */
1784 ttyprintf(tp, "%d.%02du ",
1785 utime.tv_sec, (utime.tv_usec + 5000) / 10000);
1786
1787 /* Print system time. */
1788 ttyprintf(tp, "%d.%02ds ",
1789 stime.tv_sec, (stime.tv_usec + 5000) / 10000);
1790
1791 #define pgtok(a) (((a) * NBPG) / 1024)
1792 /* Print percentage cpu, resident set size. */
1793 tmp = pick->p_pctcpu * 10000 + FSCALE / 2 >> FSHIFT;
1794 ttyprintf(tp, "%d%% %dk\n",
1795 tmp / 100,
1796 pick->p_stat == SIDL || pick->p_stat == SZOMB ? 0 :
1797 #ifdef pmap_resident_count
1798 pgtok(pmap_resident_count(&pick->p_vmspace->vm_pmap))
1799 #else
1800 pgtok(pick->p_vmspace->vm_rssize)
1801 #endif
1802 );
1803 }
1804 tp->t_rocount = 0; /* so pending input will be retyped if BS */
1805 }
1806
1807 /*
1808 * Returns 1 if p2 is "better" than p1
1809 *
1810 * The algorithm for picking the "interesting" process is thus:
1811 *
1812 * 1) Only foreground processes are eligible - implied.
1813 * 2) Runnable processes are favored over anything else. The runner
1814 * with the highest cpu utilization is picked (p_estcpu). Ties are
1815 * broken by picking the highest pid.
1816 * 3) The sleeper with the shortest sleep time is next. With ties,
1817 * we pick out just "short-term" sleepers (P_SINTR == 0).
1818 * 4) Further ties are broken by picking the highest pid.
1819 */
1820 #define ISRUN(p) (((p)->p_stat == SRUN) || ((p)->p_stat == SIDL))
1821 #define TESTAB(a, b) ((a)<<1 | (b))
1822 #define ONLYA 2
1823 #define ONLYB 1
1824 #define BOTH 3
1825
1826 static int
1827 proc_compare(p1, p2)
1828 register struct proc *p1, *p2;
1829 {
1830
1831 if (p1 == NULL)
1832 return (1);
1833 /*
1834 * see if at least one of them is runnable
1835 */
1836 switch (TESTAB(ISRUN(p1), ISRUN(p2))) {
1837 case ONLYA:
1838 return (0);
1839 case ONLYB:
1840 return (1);
1841 case BOTH:
1842 /*
1843 * tie - favor one with highest recent cpu utilization
1844 */
1845 if (p2->p_estcpu > p1->p_estcpu)
1846 return (1);
1847 if (p1->p_estcpu > p2->p_estcpu)
1848 return (0);
1849 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
1850 }
1851 /*
1852 * weed out zombies
1853 */
1854 switch (TESTAB(p1->p_stat == SZOMB, p2->p_stat == SZOMB)) {
1855 case ONLYA:
1856 return (1);
1857 case ONLYB:
1858 return (0);
1859 case BOTH:
1860 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
1861 }
1862 /*
1863 * pick the one with the smallest sleep time
1864 */
1865 if (p2->p_slptime > p1->p_slptime)
1866 return (0);
1867 if (p1->p_slptime > p2->p_slptime)
1868 return (1);
1869 /*
1870 * favor one sleeping in a non-interruptible sleep
1871 */
1872 if (p1->p_flag & P_SINTR && (p2->p_flag & P_SINTR) == 0)
1873 return (1);
1874 if (p2->p_flag & P_SINTR && (p1->p_flag & P_SINTR) == 0)
1875 return (0);
1876 return (p2->p_pid > p1->p_pid); /* tie - return highest pid */
1877 }
1878
1879 /*
1880 * Output char to tty; console putchar style.
1881 */
1882 int
1883 tputchar(c, tp)
1884 int c;
1885 struct tty *tp;
1886 {
1887 register int s;
1888
1889 s = spltty();
1890 if (ISSET(tp->t_state,
1891 TS_CARR_ON | TS_ISOPEN) != (TS_CARR_ON | TS_ISOPEN)) {
1892 splx(s);
1893 return (-1);
1894 }
1895 if (c == '\n')
1896 (void)ttyoutput('\r', tp);
1897 (void)ttyoutput(c, tp);
1898 ttstart(tp);
1899 splx(s);
1900 return (0);
1901 }
1902
1903 /*
1904 * Sleep on chan, returning ERESTART if tty changed while we napped and
1905 * returning any errors (e.g. EINTR/ETIMEDOUT) reported by tsleep. If
1906 * the tty is revoked, restarting a pending call will redo validation done
1907 * at the start of the call.
1908 */
1909 int
1910 ttysleep(tp, chan, pri, wmesg, timo)
1911 struct tty *tp;
1912 void *chan;
1913 int pri, timo;
1914 char *wmesg;
1915 {
1916 int error;
1917 short gen;
1918
1919 gen = tp->t_gen;
1920 if (error = tsleep(chan, pri, wmesg, timo))
1921 return (error);
1922 return (tp->t_gen == gen ? 0 : ERESTART);
1923 }
1924