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