Merge remote-tracking branch 'origin/vendor/GCC80'
[dragonfly.git] / sys / kern / tty.c
1 /*-
2  * (MPSAFE)
3  *
4  * Copyright (c) 1982, 1986, 1990, 1991, 1993
5  *      The Regents of the University of California.  All rights reserved.
6  * (c) UNIX System Laboratories, Inc.
7  * All or some portions of this file are derived from material licensed
8  * to the University of California by American Telephone and Telegraph
9  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
10  * the permission of UNIX System Laboratories, Inc.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  * 3. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  *
36  *      @(#)tty.c       8.8 (Berkeley) 1/21/94
37  * $FreeBSD: src/sys/kern/tty.c,v 1.129.2.5 2002/03/11 01:32:31 dd Exp $
38  */
39
40 /*
41  * MPSAFE NOTE:
42  * Almost all functions in this file are acquiring the tty token due to their
43  * access and modifications of the 'tp' (struct tty) objects.
44  */
45
46 /*-
47  * TODO:
48  *      o Fix races for sending the start char in ttyflush().
49  *      o Handle inter-byte timeout for "MIN > 0, TIME > 0" in ttyselect().
50  *        With luck, there will be MIN chars before select() returns().
51  *      o Handle CLOCAL consistently for ptys.  Perhaps disallow setting it.
52  *      o Don't allow input in TS_ZOMBIE case.  It would be visible through
53  *        FIONREAD.
54  *      o Do the new sio locking stuff here and use it to avoid special
55  *        case for EXTPROC?
56  *      o Lock PENDIN too?
57  *      o Move EXTPROC and/or PENDIN to t_state?
58  *      o Wrap most of ttioctl in spltty/splx.
59  *      o Implement TIOCNOTTY or remove it from <sys/ioctl.h>.
60  *      o Send STOP if IXOFF is toggled off while TS_TBLOCK is set.
61  *      o Don't allow certain termios flags to affect disciplines other
62  *        than TTYDISC.  Cancel their effects before switch disciplines
63  *        and ignore them if they are set while we are in another
64  *        discipline.
65  *      o Now that historical speed conversions are handled here, don't
66  *        do them in drivers.
67  *      o Check for TS_CARR_ON being set while everything is closed and not
68  *        waiting for carrier.  TS_CARR_ON isn't cleared if nothing is open,
69  *        so it would live until the next open even if carrier drops.
70  *      o Restore TS_WOPEN since it is useful in pstat.  It must be cleared
71  *        only when _all_ openers leave open().
72  */
73
74 #include "opt_uconsole.h"
75
76 #include <sys/param.h>
77 #include <sys/systm.h>
78 #include <sys/filio.h>
79 #include <sys/proc.h>
80 #include <sys/priv.h>
81 #define TTYDEFCHARS
82 #include <sys/tty.h>
83 #include <sys/clist.h>
84 #undef  TTYDEFCHARS
85 #include <sys/fcntl.h>
86 #include <sys/conf.h>
87 #include <sys/dkstat.h>
88 #include <sys/kernel.h>
89 #include <sys/vnode.h>
90 #include <sys/signalvar.h>
91 #include <sys/signal2.h>
92 #include <sys/resourcevar.h>
93 #include <sys/malloc.h>
94 #include <sys/filedesc.h>
95 #include <sys/sysctl.h>
96 #include <sys/thread2.h>
97
98 #include <vm/vm.h>
99 #include <sys/lock.h>
100 #include <vm/pmap.h>
101 #include <vm/vm_map.h>
102 #include <vm/vm_extern.h>
103
104 MALLOC_DEFINE(M_TTYS, "ttys", "tty data structures");
105
106 static int      proc_compare (struct proc *p1, struct proc *p2);
107 static int      ttnread (struct tty *tp);
108 static void     ttyecho (int c, struct tty *tp);
109 static int      ttyoutput (int c, struct tty *tp);
110 static void     ttypend (struct tty *tp);
111 static void     ttyretype (struct tty *tp);
112 static void     ttyrub (int c, struct tty *tp);
113 static void     ttyrubo (struct tty *tp, int cnt);
114 static void     ttyunblock (struct tty *tp);
115 static int      ttywflush (struct tty *tp);
116 static int      filt_ttyread (struct knote *kn, long hint);
117 static void     filt_ttyrdetach (struct knote *kn);
118 static int      filt_ttywrite (struct knote *kn, long hint);
119 static void     filt_ttywdetach (struct knote *kn);
120
121 /*
122  * Table with character classes and parity. The 8th bit indicates parity,
123  * the 7th bit indicates the character is an alphameric or underscore (for
124  * ALTWERASE), and the low 6 bits indicate delay type.  If the low 6 bits
125  * are 0 then the character needs no special processing on output; classes
126  * other than 0 might be translated or (not currently) require delays.
127  */
128 #define E       0x00    /* Even parity. */
129 #define O       0x80    /* Odd parity. */
130 #define PARITY(c)       (char_type[c] & O)
131
132 #define ALPHA   0x40    /* Alpha or underscore. */
133 #define ISALPHA(c)      (char_type[(c) & TTY_CHARMASK] & ALPHA)
134
135 #define CCLASSMASK      0x3f
136 #define CCLASS(c)       (char_type[c] & CCLASSMASK)
137
138 #define BS      BACKSPACE
139 #define CC      CONTROL
140 #define CR      RETURN
141 #define NA      ORDINARY | ALPHA
142 #define NL      NEWLINE
143 #define NO      ORDINARY
144 #define TB      TAB
145 #define VT      VTAB
146
147 static u_char const char_type[] = {
148         E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC, /* nul - bel */
149         O|BS, E|TB, E|NL, O|CC, E|VT, O|CR, O|CC, E|CC, /* bs - si */
150         O|CC, E|CC, E|CC, O|CC, E|CC, O|CC, O|CC, E|CC, /* dle - etb */
151         E|CC, O|CC, O|CC, E|CC, O|CC, E|CC, E|CC, O|CC, /* can - us */
152         O|NO, E|NO, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* sp - ' */
153         E|NO, O|NO, O|NO, E|NO, O|NO, E|NO, E|NO, O|NO, /* ( - / */
154         E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* 0 - 7 */
155         O|NA, E|NA, E|NO, O|NO, E|NO, O|NO, O|NO, E|NO, /* 8 - ? */
156         O|NO, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* @ - G */
157         E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* H - O */
158         E|NA, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* P - W */
159         O|NA, E|NA, E|NA, O|NO, E|NO, O|NO, O|NO, O|NA, /* X - _ */
160         E|NO, O|NA, O|NA, E|NA, O|NA, E|NA, E|NA, O|NA, /* ` - g */
161         O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* h - o */
162         O|NA, E|NA, E|NA, O|NA, E|NA, O|NA, O|NA, E|NA, /* p - w */
163         E|NA, O|NA, O|NA, E|NO, O|NO, E|NO, E|NO, O|CC, /* x - del */
164         /*
165          * Meta chars; should be settable per character set;
166          * for now, treat them all as normal characters.
167          */
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         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
180         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
181         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
182         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
183         NA,   NA,   NA,   NA,   NA,   NA,   NA,   NA,
184 };
185 #undef  BS
186 #undef  CC
187 #undef  CR
188 #undef  NA
189 #undef  NL
190 #undef  NO
191 #undef  TB
192 #undef  VT
193
194 /* Macros to clear/set/test flags. */
195 #define SET(t, f)       (t) |= (f)
196 #define CLR(t, f)       (t) &= ~(f)
197 #define ISSET(t, f)     ((t) & (f))
198
199 #undef MAX_INPUT                /* XXX wrong in <sys/syslimits.h> */
200 #define MAX_INPUT       TTYHOG  /* XXX limit is usually larger for !ICANON */
201
202 uint64_t tk_nin;
203 SYSCTL_OPAQUE(_kern, OID_AUTO, tk_nin, CTLFLAG_RD, &tk_nin, sizeof(tk_nin),
204     "LU", "TTY input statistic");
205 uint64_t tk_nout;
206 SYSCTL_OPAQUE(_kern, OID_AUTO, tk_nout, CTLFLAG_RD, &tk_nout, sizeof(tk_nout),
207     "LU", "TTY output statistic");
208 uint64_t tk_rawcc;
209
210 /*
211  * list of struct tty where pstat(8) can pick it up with sysctl
212  */
213 static TAILQ_HEAD(, tty) tty_list = TAILQ_HEAD_INITIALIZER(tty_list);
214
215 /*
216  * Initial open of tty, or (re)entry to standard tty line discipline.
217  */
218 int
219 ttyopen(cdev_t device, struct tty *tp)
220 {
221         crit_enter();
222         lwkt_gettoken(&tty_token);
223         tp->t_dev = device;
224         if (!ISSET(tp->t_state, TS_ISOPEN)) {
225                 SET(tp->t_state, TS_ISOPEN);
226                 if (ISSET(tp->t_cflag, CLOCAL)) {
227                         SET(tp->t_state, TS_CONNECTED);
228                 }
229                 bzero(&tp->t_winsize, sizeof(tp->t_winsize));
230         }
231         ttsetwater(tp);
232         lwkt_reltoken(&tty_token);
233         crit_exit();
234         return (0);
235 }
236
237 /*
238  * Handle close() on a tty line: flush and set to initial state,
239  * bumping generation number so that pending read/write calls
240  * can detect recycling of the tty.
241  *
242  * XXX our caller should have done `spltty(); l_close(); ttyclose();'
243  * and l_close() should have flushed, but we repeat the spltty() and
244  * the flush in case there are buggy callers.
245  */
246 int
247 ttyclose(struct tty *tp)
248 {
249         crit_enter();
250         lwkt_gettoken(&tty_token);
251         funsetown(&tp->t_sigio);
252         if (constty == tp)
253                 constty = NULL;
254
255         ttyflush(tp, FREAD | FWRITE);
256         clist_free_cblocks(&tp->t_canq);
257         clist_free_cblocks(&tp->t_outq);
258         clist_free_cblocks(&tp->t_rawq);
259
260         tp->t_gen++;
261         tp->t_line = TTYDISC;
262         ttyclearsession(tp);
263         tp->t_state &= TS_REGISTERED;   /* clear all bits except */
264         lwkt_reltoken(&tty_token);
265         crit_exit();
266         return (0);
267 }
268
269 /*
270  * Disassociate the tty from its session.  Traditionally this has only been
271  * a half-close, meaning that the session was still allowed to point at the
272  * tty (resulting in the tty in the ps command showing something like 'p0-'),
273  * even though the tty is no longer pointing at the session.
274  *
275  * The half close seems to be useful only for 'ps' output but there is as
276  * yet no reason to remove the feature.  The full-close code is currently
277  * #if 0'd out.  See also sess_rele() in kern/kern_proc.c.
278  */
279 void
280 ttyclearsession(struct tty *tp)
281 {
282         struct session *sp;
283         struct pgrp *opgrp;
284
285         lwkt_gettoken(&tty_token);
286         opgrp = tp->t_pgrp;
287         tp->t_pgrp = NULL;
288         if (opgrp) {
289                 pgrel(opgrp);
290                 opgrp = NULL;
291         }
292
293         if ((sp = tp->t_session) != NULL) {
294                 tp->t_session = NULL;
295 #ifdef TTY_DO_FULL_CLOSE
296                 /* FULL CLOSE (not yet) */
297                 if (sp->s_ttyp == tp) {
298                         sp->s_ttyp = NULL;
299                         ttyunhold(tp);
300                 } else {
301                         kprintf("ttyclearsession: warning: sp->s_ttyp != tp "
302                                 "%p/%p\n", sp->s_ttyp, tp);
303                 }
304 #endif
305         }
306         lwkt_reltoken(&tty_token);
307 }
308
309 /*
310  * Release the tty vnode association for a session.  This is the 
311  * 'other half' of the close.  Because multiple opens of /dev/tty
312  * only generate a single open to the actual tty, the file modes
313  * are locked to FREAD|FWRITE.
314  *
315  * If dorevoke is non-zero, the session is also revoked.  We have to
316  * close the vnode if VCTTYISOPEN is set.
317  */
318 void
319 ttyclosesession(struct session *sp, int dorevoke)
320 {
321         struct vnode *vp;
322
323         lwkt_gettoken(&tty_token);
324 retry:
325         /*
326          * There may not be a controlling terminal or it may have been closed
327          * out from under us.
328          */
329         if ((vp = sp->s_ttyvp) == NULL) {
330                 lwkt_reltoken(&tty_token);
331                 return;
332         }
333
334         /*
335          * We need a lock if we have to close or revoke.
336          */
337         if ((vp->v_flag & VCTTYISOPEN) || dorevoke) {
338                 vhold(vp);
339                 if (vn_lock(vp, LK_EXCLUSIVE | LK_RETRY | LK_FAILRECLAIM)) {
340                         vdrop(vp);
341                         goto retry;
342                 }
343
344                 /*
345                  * Retry if the vnode was ripped out from under us
346                  */
347                 if (vp != sp->s_ttyvp) {
348                         vn_unlock(vp);
349                         vdrop(vp);
350                         goto retry;
351                 }
352
353                 /*
354                  * Close and revoke as needed
355                  */
356                 sp->s_ttyvp = NULL;
357                 if (vp->v_flag & VCTTYISOPEN) {
358                         vclrflags(vp, VCTTYISOPEN);
359                         VOP_CLOSE(vp, FREAD|FWRITE, NULL);
360                 }
361                 vn_unlock(vp);
362                 if (dorevoke)
363                         vrevoke(vp, proc0.p_ucred);
364                 vdrop(vp);
365         } else {
366                 sp->s_ttyvp = NULL;
367         }
368         vrele(vp);
369         lwkt_reltoken(&tty_token);
370 }
371
372 #define FLUSHQ(q) {                                                     \
373         if ((q)->c_cc)                                                  \
374                 ndflush(q, (q)->c_cc);                                  \
375 }
376
377 /* Is 'c' a line delimiter ("break" character)? */
378 #define TTBREAKC(c, lflag)                                                      \
379         ((c) == '\n' || (((c) == cc[VEOF] ||                            \
380           (c) == cc[VEOL] || ((c) == cc[VEOL2] && lflag & IEXTEN)) &&   \
381          (c) != _POSIX_VDISABLE))
382
383 /*
384  * Process input of a single character received on a tty.
385  */
386 int
387 ttyinput(int c, struct tty *tp)
388 {
389         tcflag_t iflag, lflag;
390         cc_t *cc;
391         int i, err;
392
393         lwkt_gettoken(&tty_token);
394         /*
395          * If input is pending take it first.
396          */
397         lflag = tp->t_lflag;
398         if (ISSET(lflag, PENDIN))
399                 ttypend(tp);
400         /*
401          * Gather stats.
402          */
403         if (ISSET(lflag, ICANON))
404                 ++tp->t_cancc;
405         else
406                 ++tp->t_rawcc;
407         ++tk_nin;
408
409         /*
410          * Block further input iff:
411          * current input > threshold AND input is available to user program
412          * AND input flow control is enabled and not yet invoked.
413          * The 3 is slop for PARMRK.
414          */
415         iflag = tp->t_iflag;
416         if (tp->t_rawq.c_cc + tp->t_canq.c_cc > tp->t_ihiwat - 3 &&
417             (!ISSET(lflag, ICANON) || tp->t_canq.c_cc != 0) &&
418             (ISSET(tp->t_cflag, CRTS_IFLOW) || ISSET(iflag, IXOFF)) &&
419             !ISSET(tp->t_state, TS_TBLOCK))
420                 ttyblock(tp);
421
422         /* Handle exceptional conditions (break, parity, framing). */
423         cc = tp->t_cc;
424         err = (ISSET(c, TTY_ERRORMASK));
425         if (err) {
426                 CLR(c, TTY_ERRORMASK);
427                 if (ISSET(err, TTY_BI)) {
428                         if (ISSET(iflag, IGNBRK)) {
429                                 lwkt_reltoken(&tty_token);
430                                 return (0);
431                         }
432                         if (ISSET(iflag, BRKINT)) {
433                                 ttyflush(tp, FREAD | FWRITE);
434                                 pgsignal(tp->t_pgrp, SIGINT, 1);
435                                 goto endcase;
436                         }
437                         if (ISSET(iflag, PARMRK))
438                                 goto parmrk;
439                 } else if ((ISSET(err, TTY_PE) && ISSET(iflag, INPCK))
440                         || ISSET(err, TTY_FE)) {
441                         if (ISSET(iflag, IGNPAR)) {
442                                 lwkt_reltoken(&tty_token);
443                                 return (0);
444                         }
445                         else if (ISSET(iflag, PARMRK)) {
446 parmrk:
447                                 if (tp->t_rawq.c_cc + tp->t_canq.c_cc >
448                                     MAX_INPUT - 3)
449                                         goto input_overflow;
450                                 clist_putc(0377 | TTY_QUOTE, &tp->t_rawq);
451                                 clist_putc(0 | TTY_QUOTE, &tp->t_rawq);
452                                 clist_putc(c | TTY_QUOTE, &tp->t_rawq);
453                                 goto endcase;
454                         } else
455                                 c = 0;
456                 }
457         }
458
459         if (!ISSET(tp->t_state, TS_TYPEN) && ISSET(iflag, ISTRIP))
460                 CLR(c, 0x80);
461         if (!ISSET(lflag, EXTPROC)) {
462                 /*
463                  * Check for literal nexting very first
464                  */
465                 if (ISSET(tp->t_state, TS_LNCH)) {
466                         SET(c, TTY_QUOTE);
467                         CLR(tp->t_state, TS_LNCH);
468                 }
469                 /*
470                  * Scan for special characters.  This code
471                  * is really just a big case statement with
472                  * non-constant cases.  The bottom of the
473                  * case statement is labeled ``endcase'', so goto
474                  * it after a case match, or similar.
475                  */
476
477                 /*
478                  * Control chars which aren't controlled
479                  * by ICANON, ISIG, or IXON.
480                  */
481                 if (ISSET(lflag, IEXTEN)) {
482                         if (CCEQ(cc[VLNEXT], c)) {
483                                 if (ISSET(lflag, ECHO)) {
484                                         if (ISSET(lflag, ECHOE)) {
485                                                 (void)ttyoutput('^', tp);
486                                                 (void)ttyoutput('\b', tp);
487                                         } else
488                                                 ttyecho(c, tp);
489                                 }
490                                 SET(tp->t_state, TS_LNCH);
491                                 goto endcase;
492                         }
493                         if (CCEQ(cc[VDISCARD], c)) {
494                                 if (ISSET(lflag, FLUSHO))
495                                         CLR(tp->t_lflag, FLUSHO);
496                                 else {
497                                         ttyflush(tp, FWRITE);
498                                         ttyecho(c, tp);
499                                         if (tp->t_rawq.c_cc + tp->t_canq.c_cc)
500                                                 ttyretype(tp);
501                                         SET(tp->t_lflag, FLUSHO);
502                                 }
503                                 goto startoutput;
504                         }
505                 }
506                 /*
507                  * Signals.
508                  */
509                 if (ISSET(lflag, ISIG)) {
510                         if (CCEQ(cc[VINTR], c) || CCEQ(cc[VQUIT], c)) {
511                                 if (!ISSET(lflag, NOFLSH))
512                                         ttyflush(tp, FREAD | FWRITE);
513                                 ttyecho(c, tp);
514                                 pgsignal(tp->t_pgrp,
515                                     CCEQ(cc[VINTR], c) ? SIGINT : SIGQUIT, 1);
516                                 goto endcase;
517                         }
518                         if (CCEQ(cc[VSUSP], c)) {
519                                 if (!ISSET(lflag, NOFLSH))
520                                         ttyflush(tp, FREAD);
521                                 ttyecho(c, tp);
522                                 pgsignal(tp->t_pgrp, SIGTSTP, 1);
523                                 goto endcase;
524                         }
525                 }
526                 /*
527                  * Handle start/stop characters.
528                  */
529                 if (ISSET(iflag, IXON)) {
530                         if (CCEQ(cc[VSTOP], c)) {
531                                 if (!ISSET(tp->t_state, TS_TTSTOP)) {
532                                         SET(tp->t_state, TS_TTSTOP);
533                                         (*tp->t_stop)(tp, 0);
534                                         lwkt_reltoken(&tty_token);
535                                         return (0);
536                                 }
537                                 if (!CCEQ(cc[VSTART], c)) {
538                                         lwkt_reltoken(&tty_token);
539                                         return (0);
540                                 }
541                                 /*
542                                  * if VSTART == VSTOP then toggle
543                                  */
544                                 goto endcase;
545                         }
546                         if (CCEQ(cc[VSTART], c))
547                                 goto restartoutput;
548                 }
549                 /*
550                  * IGNCR, ICRNL, & INLCR
551                  */
552                 if (c == '\r') {
553                         if (ISSET(iflag, IGNCR)) {
554                                 lwkt_reltoken(&tty_token);
555                                 return (0);
556                         }
557                         else if (ISSET(iflag, ICRNL))
558                                 c = '\n';
559                 } else if (c == '\n' && ISSET(iflag, INLCR))
560                         c = '\r';
561         }
562         if (!ISSET(tp->t_lflag, EXTPROC) && ISSET(lflag, ICANON)) {
563                 /*
564                  * From here on down canonical mode character
565                  * processing takes place.
566                  */
567                 /*
568                  * erase or erase2 (^H / ^?)
569                  */
570                 if (CCEQ(cc[VERASE], c) || CCEQ(cc[VERASE2], c) ) {
571                         if (tp->t_rawq.c_cc)
572                                 ttyrub(clist_unputc(&tp->t_rawq), tp);
573                         goto endcase;
574                 }
575                 /*
576                  * kill (^U)
577                  */
578                 if (CCEQ(cc[VKILL], c)) {
579                         if (ISSET(lflag, ECHOKE) &&
580                             tp->t_rawq.c_cc == tp->t_rocount &&
581                             !ISSET(lflag, ECHOPRT))
582                                 while (tp->t_rawq.c_cc)
583                                         ttyrub(clist_unputc(&tp->t_rawq), tp);
584                         else {
585                                 ttyecho(c, tp);
586                                 if (ISSET(lflag, ECHOK) ||
587                                     ISSET(lflag, ECHOKE))
588                                         ttyecho('\n', tp);
589                                 FLUSHQ(&tp->t_rawq);
590                                 tp->t_rocount = 0;
591                         }
592                         CLR(tp->t_state, TS_LOCAL);
593                         goto endcase;
594                 }
595                 /*
596                  * word erase (^W)
597                  */
598                 if (CCEQ(cc[VWERASE], c) && ISSET(lflag, IEXTEN)) {
599                         int ctype;
600
601                         /*
602                          * erase whitespace
603                          */
604                         while ((c = clist_unputc(&tp->t_rawq)) == ' ' || c == '\t')
605                                 ttyrub(c, tp);
606                         if (c == -1)
607                                 goto endcase;
608                         /*
609                          * erase last char of word and remember the
610                          * next chars type (for ALTWERASE)
611                          */
612                         ttyrub(c, tp);
613                         c = clist_unputc(&tp->t_rawq);
614                         if (c == -1)
615                                 goto endcase;
616                         if (c == ' ' || c == '\t') {
617                                 clist_putc(c, &tp->t_rawq);
618                                 goto endcase;
619                         }
620                         ctype = ISALPHA(c);
621                         /*
622                          * erase rest of word
623                          */
624                         do {
625                                 ttyrub(c, tp);
626                                 c = clist_unputc(&tp->t_rawq);
627                                 if (c == -1)
628                                         goto endcase;
629                         } while (c != ' ' && c != '\t' &&
630                             (!ISSET(lflag, ALTWERASE) || ISALPHA(c) == ctype));
631                         clist_putc(c, &tp->t_rawq);
632                         goto endcase;
633                 }
634                 /*
635                  * reprint line (^R)
636                  */
637                 if (CCEQ(cc[VREPRINT], c) && ISSET(lflag, IEXTEN)) {
638                         ttyretype(tp);
639                         goto endcase;
640                 }
641                 /*
642                  * ^T - kernel info and generate SIGINFO
643                  */
644                 if (CCEQ(cc[VSTATUS], c) && ISSET(lflag, IEXTEN)) {
645                         if (ISSET(lflag, ISIG))
646                                 pgsignal(tp->t_pgrp, SIGINFO, 1);
647                         if (!ISSET(lflag, NOKERNINFO))
648                                 ttyinfo(tp);
649                         goto endcase;
650                 }
651                 if (CCEQ(cc[VCHECKPT], c) && ISSET(lflag, IEXTEN)) {
652                         if (ISSET(lflag, ISIG))
653                                 pgsignal(tp->t_pgrp, SIGCKPT, 1);
654                         goto endcase;
655                 }
656         }
657         /*
658          * Check for input buffer overflow
659          */
660         if (tp->t_rawq.c_cc + tp->t_canq.c_cc >= MAX_INPUT) {
661 input_overflow:
662                 if (ISSET(iflag, IMAXBEL)) {
663                         if (tp->t_outq.c_cc < tp->t_ohiwat)
664                                 (void)ttyoutput(CTRL('g'), tp);
665                 }
666                 goto endcase;
667         }
668
669         if (   c == 0377 && ISSET(iflag, PARMRK) && !ISSET(iflag, ISTRIP)
670              && ISSET(iflag, IGNBRK|IGNPAR) != (IGNBRK|IGNPAR))
671                 clist_putc(0377 | TTY_QUOTE, &tp->t_rawq);
672
673         /*
674          * Put data char in q for user and
675          * wakeup on seeing a line delimiter.
676          */
677         if (clist_putc(c, &tp->t_rawq) >= 0) {
678                 if (!ISSET(lflag, ICANON)) {
679                         ttwakeup(tp);
680                         ttyecho(c, tp);
681                         goto endcase;
682                 }
683                 if (TTBREAKC(c, lflag)) {
684                         tp->t_rocount = 0;
685                         catq(&tp->t_rawq, &tp->t_canq);
686                         ttwakeup(tp);
687                 } else if (tp->t_rocount++ == 0)
688                         tp->t_rocol = tp->t_column;
689                 if (ISSET(tp->t_state, TS_ERASE)) {
690                         /*
691                          * end of prterase \.../
692                          */
693                         CLR(tp->t_state, TS_ERASE);
694                         (void)ttyoutput('/', tp);
695                 }
696                 i = tp->t_column;
697                 ttyecho(c, tp);
698                 if (CCEQ(cc[VEOF], c) && ISSET(lflag, ECHO)) {
699                         /*
700                          * Place the cursor over the '^' of the ^D.
701                          */
702                         i = imin(2, tp->t_column - i);
703                         while (i > 0) {
704                                 (void)ttyoutput('\b', tp);
705                                 i--;
706                         }
707                 }
708         }
709 endcase:
710         /*
711          * IXANY means allow any character to restart output.
712          */
713         if (ISSET(tp->t_state, TS_TTSTOP) &&
714             !ISSET(iflag, IXANY) && cc[VSTART] != cc[VSTOP]) {
715                 lwkt_reltoken(&tty_token);
716                 return (0);
717         }
718 restartoutput:
719         CLR(tp->t_lflag, FLUSHO);
720         CLR(tp->t_state, TS_TTSTOP);
721 startoutput:
722         lwkt_reltoken(&tty_token);
723         return (ttstart(tp));
724 }
725
726 /*
727  * Output a single character on a tty, doing output processing
728  * as needed (expanding tabs, newline processing, etc.).
729  * Returns < 0 if succeeds, otherwise returns char to resend.
730  * Must be recursive.
731  */
732 static int
733 ttyoutput(int c, struct tty *tp)
734 {
735         tcflag_t oflag;
736         int col;
737
738         lwkt_gettoken(&tty_token);
739         oflag = tp->t_oflag;
740         if (!ISSET(oflag, OPOST)) {
741                 if (ISSET(tp->t_lflag, FLUSHO)) {
742                         lwkt_reltoken(&tty_token);
743                         return (-1);
744                 }
745                 if (clist_putc(c, &tp->t_outq)) {
746                         lwkt_reltoken(&tty_token);
747                         return (c);
748                 }
749                 tk_nout++;
750                 tp->t_outcc++;
751                 lwkt_reltoken(&tty_token);
752                 return (-1);
753         }
754         /*
755          * Do tab expansion if OXTABS is set.  Special case if we external
756          * processing, we don't do the tab expansion because we'll probably
757          * get it wrong.  If tab expansion needs to be done, let it happen
758          * externally.
759          */
760         CLR(c, ~TTY_CHARMASK);
761         if (c == '\t' &&
762             ISSET(oflag, OXTABS) && !ISSET(tp->t_lflag, EXTPROC)) {
763                 c = 8 - (tp->t_column & 7);
764                 if (!ISSET(tp->t_lflag, FLUSHO)) {
765                         crit_enter();           /* Don't interrupt tabs. */
766                         c -= b_to_q("        ", c, &tp->t_outq);
767                         tk_nout += c;
768                         tp->t_outcc += c;
769                         crit_exit();
770                 }
771                 tp->t_column += c;
772                 lwkt_reltoken(&tty_token);
773                 return (c ? -1 : '\t');
774         }
775         if (c == CEOT && ISSET(oflag, ONOEOT)) {
776                 lwkt_reltoken(&tty_token);
777                 return (-1);
778         }
779
780         /*
781          * Newline translation: if ONLCR is set,
782          * translate newline into "\r\n".
783          */
784         if (c == '\n' && ISSET(tp->t_oflag, ONLCR)) {
785                 tk_nout++;
786                 tp->t_outcc++;
787                 if (!ISSET(tp->t_lflag, FLUSHO) && clist_putc('\r', &tp->t_outq)) {
788                         lwkt_reltoken(&tty_token);
789                         return (c);
790                 }
791         }
792         /* If OCRNL is set, translate "\r" into "\n". */
793         else if (c == '\r' && ISSET(tp->t_oflag, OCRNL))
794                 c = '\n';
795         /* If ONOCR is set, don't transmit CRs when on column 0. */
796         else if (c == '\r' && ISSET(tp->t_oflag, ONOCR) && tp->t_column == 0) {
797                 lwkt_reltoken(&tty_token);
798                 return (-1);
799         }
800
801         tk_nout++;
802         tp->t_outcc++;
803         if (!ISSET(tp->t_lflag, FLUSHO) && clist_putc(c, &tp->t_outq)) {
804                 lwkt_reltoken(&tty_token);
805                 return (c);
806         }
807
808         col = tp->t_column;
809         switch (CCLASS(c)) {
810         case BACKSPACE:
811                 if (col > 0)
812                         --col;
813                 break;
814         case CONTROL:
815                 break;
816         case NEWLINE:
817                 if (ISSET(tp->t_oflag, ONLCR | ONLRET))
818                         col = 0;
819                 break;
820         case RETURN:
821                 col = 0;
822                 break;
823         case ORDINARY:
824                 ++col;
825                 break;
826         case TAB:
827                 col = (col + 8) & ~7;
828                 break;
829         }
830         tp->t_column = col;
831         lwkt_reltoken(&tty_token);
832         return (-1);
833 }
834
835 /*
836  * Ioctls for all tty devices.  Called after line-discipline specific ioctl
837  * has been called to do discipline-specific functions and/or reject any
838  * of these ioctl commands.
839  */
840 /* ARGSUSED */
841 int
842 ttioctl(struct tty *tp, u_long cmd, void *data, int flag)
843 {
844         struct thread *td = curthread;
845         struct lwp *lp = td->td_lwp;
846         struct proc *p = td->td_proc;
847         struct pgrp *opgrp;
848         struct tty *otp;
849         int error;
850
851         KKASSERT(p);
852         lwkt_gettoken(&tty_token);
853         lwkt_gettoken(&p->p_token);
854
855         /* If the ioctl involves modification, hang if in the background. */
856         switch (cmd) {
857         case  TIOCCBRK:
858         case  TIOCCONS:
859         case  TIOCDRAIN:
860         case  TIOCEXCL:
861         case  TIOCFLUSH:
862 #ifdef TIOCHPCL
863         case  TIOCHPCL:
864 #endif
865         case  TIOCNXCL:
866         case  TIOCSBRK:
867         case  TIOCSCTTY:
868         case  TIOCSDRAINWAIT:
869         case  TIOCSETA:
870         case  TIOCSETAF:
871         case  TIOCSETAW:
872         case  TIOCSETD:
873         case  TIOCSPGRP:
874         case  TIOCSTART:
875         case  TIOCSTAT:
876         case  TIOCSTI:
877         case  TIOCSTOP:
878         case  TIOCSWINSZ:
879                 while (isbackground(p, tp) && !(p->p_flags & P_PPWAIT) &&
880                     !SIGISMEMBER(p->p_sigignore, SIGTTOU) &&
881                     !SIGISMEMBER(lp->lwp_sigmask, SIGTTOU)) {
882                         if (p->p_pgrp->pg_jobc == 0) {
883                                 lwkt_reltoken(&p->p_token);
884                                 lwkt_reltoken(&tty_token);
885                                 return (EIO);
886                         }
887                         pgsignal(p->p_pgrp, SIGTTOU, 1);
888                         error = ttysleep(tp, &lbolt, PCATCH, "ttybg1",
889                                          0);
890                         if (error) {
891                                 lwkt_reltoken(&p->p_token);
892                                 lwkt_reltoken(&tty_token);
893                                 return (error);
894                         }
895                 }
896                 break;
897         }
898
899         switch (cmd) {                  /* Process the ioctl. */
900         case FIOASYNC:                  /* set/clear async i/o */
901                 crit_enter();
902                 if (*(int *)data)
903                         SET(tp->t_state, TS_ASYNC);
904                 else
905                         CLR(tp->t_state, TS_ASYNC);
906                 crit_exit();
907                 break;
908         case FIONREAD:                  /* get # bytes to read */
909                 crit_enter();
910                 *(int *)data = ttnread(tp);
911                 crit_exit();
912                 break;
913
914         case FIOSETOWN:
915                 /*
916                  * Policy -- Don't allow FIOSETOWN on someone else's 
917                  *           controlling tty
918                  */
919                 if (tp->t_session != NULL && !isctty(p, tp)) {
920                         lwkt_reltoken(&p->p_token);
921                         lwkt_reltoken(&tty_token);
922                         return (ENOTTY);
923                 }
924
925                 error = fsetown(*(int *)data, &tp->t_sigio);
926                 if (error) {
927                         lwkt_reltoken(&p->p_token);
928                         lwkt_reltoken(&tty_token);
929                         return (error);
930                 }
931                 break;
932         case FIOGETOWN:
933                 if (tp->t_session != NULL && !isctty(p, tp)) {
934                         lwkt_reltoken(&p->p_token);
935                         lwkt_reltoken(&tty_token);
936                         return (ENOTTY);
937                 }
938                 *(int *)data = fgetown(&tp->t_sigio);
939                 break;
940
941         case TIOCEXCL:                  /* set exclusive use of tty */
942                 crit_enter();
943                 SET(tp->t_state, TS_XCLUDE);
944                 crit_exit();
945                 break;
946         case TIOCFLUSH: {               /* flush buffers */
947                 int flags = *(int *)data;
948
949                 if (flags == 0)
950                         flags = FREAD | FWRITE;
951                 else
952                         flags &= FREAD | FWRITE;
953                 ttyflush(tp, flags);
954                 break;
955         }
956         case TIOCCONS:                  /* become virtual console */
957                 if (*(int *)data) {
958                         if (constty && constty != tp &&
959                             ISSET(constty->t_state, TS_CONNECTED)) {
960                                 lwkt_reltoken(&p->p_token);
961                                 lwkt_reltoken(&tty_token);
962                                 return (EBUSY);
963                         }
964 #ifndef UCONSOLE
965                         if ((error = priv_check(td, PRIV_ROOT)) != 0) {
966                                 lwkt_reltoken(&p->p_token);
967                                 lwkt_reltoken(&tty_token);
968                                 return (error);
969                         }
970 #endif
971                         constty = tp;
972                 } else if (tp == constty)
973                         constty = NULL;
974                 break;
975         case TIOCDRAIN:                 /* wait till output drained */
976                 error = ttywait(tp);
977                 if (error) {
978                         lwkt_reltoken(&p->p_token);
979                         lwkt_reltoken(&tty_token);
980                         return (error);
981                 }
982                 break;
983         case TIOCGETA: {                /* get termios struct */
984                 struct termios *t = (struct termios *)data;
985
986                 bcopy(&tp->t_termios, t, sizeof(struct termios));
987                 break;
988         }
989         case TIOCGETD:                  /* get line discipline */
990                 *(int *)data = tp->t_line;
991                 break;
992         case TIOCGWINSZ:                /* get window size */
993                 *(struct winsize *)data = tp->t_winsize;
994                 break;
995         case TIOCGPGRP:                 /* get pgrp of tty */
996                 if (!isctty(p, tp)) {
997                         lwkt_reltoken(&p->p_token);
998                         lwkt_reltoken(&tty_token);
999                         return (ENOTTY);
1000                 }
1001                 *(int *)data = tp->t_pgrp ? tp->t_pgrp->pg_id : NO_PID;
1002                 break;
1003         case TIOCGSID:                  /* get sid of tty */
1004                 if (!isctty(p, tp)) {
1005                         lwkt_reltoken(&p->p_token);
1006                         lwkt_reltoken(&tty_token);
1007                         return (ENOTTY);
1008                 }
1009                 *(int *)data = tp->t_session->s_sid;
1010                 break;
1011 #ifdef TIOCHPCL
1012         case TIOCHPCL:                  /* hang up on last close */
1013                 crit_enter();
1014                 SET(tp->t_cflag, HUPCL);
1015                 crit_exit();
1016                 break;
1017 #endif
1018         case TIOCNXCL:                  /* reset exclusive use of tty */
1019                 crit_enter();
1020                 CLR(tp->t_state, TS_XCLUDE);
1021                 crit_exit();
1022                 break;
1023         case TIOCOUTQ:                  /* output queue size */
1024                 *(int *)data = tp->t_outq.c_cc;
1025                 break;
1026         case TIOCSETA:                  /* set termios struct */
1027         case TIOCSETAW:                 /* drain output, set */
1028         case TIOCSETAF: {               /* drn out, fls in, set */
1029                 struct termios *t = (struct termios *)data;
1030
1031                 if (t->c_ispeed == 0)
1032                         t->c_ispeed = t->c_ospeed;
1033                 if (t->c_ispeed == 0)
1034                         t->c_ispeed = tp->t_ospeed;
1035                 if (t->c_ispeed == 0) {
1036                         lwkt_reltoken(&p->p_token);
1037                         lwkt_reltoken(&tty_token);
1038                         return (EINVAL);
1039                 }
1040                 crit_enter();
1041                 if (cmd == TIOCSETAW || cmd == TIOCSETAF) {
1042                         error = ttywait(tp);
1043                         if (error) {
1044                                 crit_exit();
1045                                 lwkt_reltoken(&p->p_token);
1046                                 lwkt_reltoken(&tty_token);
1047                                 return (error);
1048                         }
1049                         if (cmd == TIOCSETAF)
1050                                 ttyflush(tp, FREAD);
1051                 }
1052                 if (!ISSET(t->c_cflag, CIGNORE)) {
1053                         /*
1054                          * Set device hardware.
1055                          */
1056                         if (tp->t_param && (error = (*tp->t_param)(tp, t))) {
1057                                 crit_exit();
1058                                 lwkt_reltoken(&p->p_token);
1059                                 lwkt_reltoken(&tty_token);
1060                                 return (error);
1061                         }
1062                         if (ISSET(t->c_cflag, CLOCAL) &&
1063                             !ISSET(tp->t_cflag, CLOCAL)) {
1064                                 /*
1065                                  * XXX disconnections would be too hard to
1066                                  * get rid of without this kludge.  The only
1067                                  * way to get rid of controlling terminals
1068                                  * is to exit from the session leader.
1069                                  */
1070                                 CLR(tp->t_state, TS_ZOMBIE);
1071
1072                                 wakeup(TSA_CARR_ON(tp));
1073                                 ttwakeup(tp);
1074                                 ttwwakeup(tp);
1075                         }
1076                         if ((ISSET(tp->t_state, TS_CARR_ON) ||
1077                              ISSET(t->c_cflag, CLOCAL)) &&
1078                             !ISSET(tp->t_state, TS_ZOMBIE))
1079                                 SET(tp->t_state, TS_CONNECTED);
1080                         else
1081                                 CLR(tp->t_state, TS_CONNECTED);
1082                         tp->t_cflag = t->c_cflag;
1083                         tp->t_ispeed = t->c_ispeed;
1084                         if (t->c_ospeed != 0)
1085                                 tp->t_ospeed = t->c_ospeed;
1086                         ttsetwater(tp);
1087                 }
1088                 if (ISSET(t->c_lflag, ICANON) != ISSET(tp->t_lflag, ICANON) &&
1089                     cmd != TIOCSETAF) {
1090                         if (ISSET(t->c_lflag, ICANON))
1091                                 SET(tp->t_lflag, PENDIN);
1092                         else {
1093                                 /*
1094                                  * XXX we really shouldn't allow toggling
1095                                  * ICANON while we're in a non-termios line
1096                                  * discipline.  Now we have to worry about
1097                                  * panicing for a null queue.
1098                                  */
1099                                 if (tp->t_canq.c_cbreserved > 0 &&
1100                                     tp->t_rawq.c_cbreserved > 0) {
1101                                         catq(&tp->t_rawq, &tp->t_canq);
1102                                         /*
1103                                          * XXX the queue limits may be
1104                                          * different, so the old queue
1105                                          * swapping method no longer works.
1106                                          */
1107                                         catq(&tp->t_canq, &tp->t_rawq);
1108                                 }
1109                                 CLR(tp->t_lflag, PENDIN);
1110                         }
1111                         ttwakeup(tp);
1112                 }
1113                 tp->t_iflag = t->c_iflag;
1114                 tp->t_oflag = t->c_oflag;
1115                 /*
1116                  * Make the EXTPROC bit read only.
1117                  */
1118                 if (ISSET(tp->t_lflag, EXTPROC))
1119                         SET(t->c_lflag, EXTPROC);
1120                 else
1121                         CLR(t->c_lflag, EXTPROC);
1122                 tp->t_lflag = t->c_lflag | ISSET(tp->t_lflag, PENDIN);
1123                 if (t->c_cc[VMIN] != tp->t_cc[VMIN] ||
1124                     t->c_cc[VTIME] != tp->t_cc[VTIME])
1125                         ttwakeup(tp);
1126                 bcopy(t->c_cc, tp->t_cc, sizeof(t->c_cc));
1127                 crit_exit();
1128                 break;
1129         }
1130         case TIOCSETD: {                /* set line discipline */
1131                 int t = *(int *)data;
1132                 cdev_t device = tp->t_dev;
1133
1134                 if ((u_int)t >= nlinesw) {
1135                         lwkt_reltoken(&p->p_token);
1136                         lwkt_reltoken(&tty_token);
1137                         return (ENXIO);
1138                 }
1139                 if (t != tp->t_line) {
1140                         crit_enter();
1141                         (*linesw[tp->t_line].l_close)(tp, flag);
1142                         error = (*linesw[t].l_open)(device, tp);
1143                         if (error) {
1144                                 (void)(*linesw[tp->t_line].l_open)(device, tp);
1145                                 crit_exit();
1146                                 lwkt_reltoken(&p->p_token);
1147                                 lwkt_reltoken(&tty_token);
1148                                 return (error);
1149                         }
1150                         tp->t_line = t;
1151                         crit_exit();
1152                 }
1153                 break;
1154         }
1155         case TIOCSTART:                 /* start output, like ^Q */
1156                 crit_enter();
1157                 if (ISSET(tp->t_state, TS_TTSTOP) ||
1158                     ISSET(tp->t_lflag, FLUSHO)) {
1159                         CLR(tp->t_lflag, FLUSHO);
1160                         CLR(tp->t_state, TS_TTSTOP);
1161                         ttstart(tp);
1162                 }
1163                 crit_exit();
1164                 break;
1165         case TIOCSTI:                   /* simulate terminal input */
1166                 if ((flag & FREAD) == 0 && priv_check(td, PRIV_ROOT)) {
1167                         lwkt_reltoken(&p->p_token);
1168                         lwkt_reltoken(&tty_token);
1169                         return (EPERM);
1170                 }
1171                 if (!isctty(p, tp) && priv_check(td, PRIV_ROOT)) {
1172                         lwkt_reltoken(&p->p_token);
1173                         lwkt_reltoken(&tty_token);
1174                         return (EACCES);
1175                 }
1176                 crit_enter();
1177                 (*linesw[tp->t_line].l_rint)(*(u_char *)data, tp);
1178                 crit_exit();
1179                 break;
1180         case TIOCSTOP:                  /* stop output, like ^S */
1181                 crit_enter();
1182                 if (!ISSET(tp->t_state, TS_TTSTOP)) {
1183                         SET(tp->t_state, TS_TTSTOP);
1184                         (*tp->t_stop)(tp, 0);
1185                 }
1186                 crit_exit();
1187                 break;
1188         case TIOCSCTTY:                 /* become controlling tty */
1189                 /* Session ctty vnode pointer set in vnode layer. */
1190                 if (!SESS_LEADER(p) ||
1191                     ((p->p_session->s_ttyvp || tp->t_session) &&
1192                     (tp->t_session != p->p_session))) {
1193                         lwkt_reltoken(&p->p_token);
1194                         lwkt_reltoken(&tty_token);
1195                         return (EPERM);
1196                 }
1197                 ttyhold(tp);
1198                 tp->t_session = p->p_session;
1199                 opgrp = tp->t_pgrp;
1200                 pgref(p->p_pgrp);
1201                 tp->t_pgrp = p->p_pgrp;
1202                 otp = p->p_session->s_ttyp;
1203                 p->p_session->s_ttyp = tp;
1204                 p->p_flags |= P_CONTROLT;
1205                 if (otp)
1206                         ttyunhold(otp);
1207                 if (opgrp) {
1208                         pgrel(opgrp);
1209                         opgrp = NULL;
1210                 }
1211                 break;
1212         case TIOCSPGRP: {               /* set pgrp of tty */
1213                 pid_t pgid = *(int *)data;
1214
1215                 if (!isctty(p, tp)) {
1216                         lwkt_reltoken(&p->p_token);
1217                         lwkt_reltoken(&tty_token);
1218                         return (ENOTTY);
1219                 }
1220                 else if (pgid < 1 || pgid > PID_MAX) {
1221                         lwkt_reltoken(&p->p_token);
1222                         lwkt_reltoken(&tty_token);
1223                         return (EINVAL);
1224                 } else {
1225                         struct pgrp *pgrp = pgfind(pgid);
1226                         if (pgrp == NULL || pgrp->pg_session != p->p_session) {
1227                                 if (pgrp)
1228                                         pgrel(pgrp);
1229                                 lwkt_reltoken(&p->p_token);
1230                                 lwkt_reltoken(&tty_token);
1231                                 return (EPERM);
1232                         }
1233                         opgrp = tp->t_pgrp;
1234                         tp->t_pgrp = pgrp;
1235                         if (opgrp) {
1236                                 pgrel(opgrp);
1237                                 opgrp = NULL;
1238                         }
1239                 }
1240                 break;
1241         }
1242         case TIOCSTAT:                  /* simulate control-T */
1243                 crit_enter();
1244                 ttyinfo(tp);
1245                 crit_exit();
1246                 break;
1247         case TIOCSWINSZ:                /* set window size */
1248                 if (bcmp((caddr_t)&tp->t_winsize, data,
1249                     sizeof (struct winsize))) {
1250                         tp->t_winsize = *(struct winsize *)data;
1251                         pgsignal(tp->t_pgrp, SIGWINCH, 1);
1252                 }
1253                 break;
1254         case TIOCSDRAINWAIT:
1255                 error = priv_check(td, PRIV_ROOT);
1256                 if (error) {
1257                         lwkt_reltoken(&p->p_token);
1258                         lwkt_reltoken(&tty_token);
1259                         return (error);
1260                 }
1261                 tp->t_timeout = *(int *)data * hz;
1262                 wakeup(TSA_OCOMPLETE(tp));
1263                 wakeup(TSA_OLOWAT(tp));
1264                 break;
1265         case TIOCGDRAINWAIT:
1266                 *(int *)data = tp->t_timeout / hz;
1267                 break;
1268         default:
1269                 lwkt_reltoken(&p->p_token);
1270                 lwkt_reltoken(&tty_token);
1271                 return (ENOIOCTL);
1272         }
1273         lwkt_reltoken(&p->p_token);
1274         lwkt_reltoken(&tty_token);
1275         return (0);
1276 }
1277
1278 static struct filterops ttyread_filtops =
1279         { FILTEROP_ISFD|FILTEROP_MPSAFE, NULL, filt_ttyrdetach, filt_ttyread };
1280 static struct filterops ttywrite_filtops =
1281         { FILTEROP_ISFD|FILTEROP_MPSAFE, NULL, filt_ttywdetach, filt_ttywrite };
1282
1283 int
1284 ttykqfilter(struct dev_kqfilter_args *ap)
1285 {
1286         cdev_t dev = ap->a_head.a_dev;
1287         struct knote *kn = ap->a_kn;
1288         struct tty *tp = dev->si_tty;
1289         struct klist *klist;
1290
1291         ap->a_result = 0;
1292
1293         lwkt_gettoken(&tty_token);
1294         switch (kn->kn_filter) {
1295         case EVFILT_READ:
1296                 klist = &tp->t_rkq.ki_note;
1297                 kn->kn_fop = &ttyread_filtops;
1298                 break;
1299         case EVFILT_WRITE:
1300                 klist = &tp->t_wkq.ki_note;
1301                 kn->kn_fop = &ttywrite_filtops;
1302                 break;
1303         default:
1304                 ap->a_result = EOPNOTSUPP;
1305                 lwkt_reltoken(&tty_token);
1306                 return (0);
1307         }
1308         lwkt_reltoken(&tty_token);
1309         kn->kn_hook = (caddr_t)dev;
1310         knote_insert(klist, kn);
1311
1312         return (0);
1313 }
1314
1315 static void
1316 filt_ttyrdetach(struct knote *kn)
1317 {
1318         struct tty *tp = ((cdev_t)kn->kn_hook)->si_tty;
1319
1320         lwkt_gettoken(&tty_token);
1321         knote_remove(&tp->t_rkq.ki_note, kn);
1322         lwkt_reltoken(&tty_token);
1323 }
1324
1325 static int
1326 filt_ttyread(struct knote *kn, long hint)
1327 {
1328         struct tty *tp = ((cdev_t)kn->kn_hook)->si_tty;
1329
1330         lwkt_gettoken(&tty_token);
1331         kn->kn_data = ttnread(tp);
1332         if (ISSET(tp->t_state, TS_ZOMBIE)) {
1333                 kn->kn_flags |= (EV_EOF | EV_NODATA);
1334                 lwkt_reltoken(&tty_token);
1335                 return (1);
1336         }
1337         lwkt_reltoken(&tty_token);
1338         return (kn->kn_data > 0);
1339 }
1340
1341 static void
1342 filt_ttywdetach(struct knote *kn)
1343 {
1344         struct tty *tp = ((cdev_t)kn->kn_hook)->si_tty;
1345
1346         lwkt_gettoken(&tty_token);
1347         knote_remove(&tp->t_wkq.ki_note, kn);
1348         lwkt_reltoken(&tty_token);
1349 }
1350
1351 static int
1352 filt_ttywrite(struct knote *kn, long hint)
1353 {
1354         struct tty *tp = ((cdev_t)kn->kn_hook)->si_tty;
1355         int ret;
1356
1357         lwkt_gettoken(&tty_token);
1358         kn->kn_data = tp->t_outq.c_cc;
1359         if (ISSET(tp->t_state, TS_ZOMBIE)) {
1360                 lwkt_reltoken(&tty_token);
1361                 return (1);
1362         }
1363         ret = (kn->kn_data <= tp->t_olowat &&
1364             ISSET(tp->t_state, TS_CONNECTED));
1365         lwkt_reltoken(&tty_token);
1366         return ret;
1367 }
1368
1369 /*
1370  * Must be called while in a critical section.
1371  * NOTE: tty_token must be held.
1372  */
1373 static int
1374 ttnread(struct tty *tp)
1375 {
1376         int nread;
1377
1378         ASSERT_LWKT_TOKEN_HELD(&tty_token);
1379         if (ISSET(tp->t_lflag, PENDIN))
1380                 ttypend(tp);
1381         nread = tp->t_canq.c_cc;
1382         if (!ISSET(tp->t_lflag, ICANON)) {
1383                 nread += tp->t_rawq.c_cc;
1384                 if (nread < tp->t_cc[VMIN] && tp->t_cc[VTIME] == 0)
1385                         nread = 0;
1386         }
1387         return (nread);
1388 }
1389
1390 /*
1391  * Wait for output to drain.
1392  */
1393 int
1394 ttywait(struct tty *tp)
1395 {
1396         int error;
1397
1398         error = 0;
1399         crit_enter();
1400         lwkt_gettoken(&tty_token);
1401         while ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
1402                ISSET(tp->t_state, TS_CONNECTED) && tp->t_oproc) {
1403                 (*tp->t_oproc)(tp);
1404                 if ((tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)) &&
1405                     ISSET(tp->t_state, TS_CONNECTED)) {
1406                         SET(tp->t_state, TS_SO_OCOMPLETE);
1407                         error = ttysleep(tp, TSA_OCOMPLETE(tp),
1408                                          PCATCH, "ttywai",
1409                                          tp->t_timeout);
1410                         if (error) {
1411                                 if (error == EWOULDBLOCK)
1412                                         error = EIO;
1413                                 break;
1414                         }
1415                 } else
1416                         break;
1417         }
1418         if (!error && (tp->t_outq.c_cc || ISSET(tp->t_state, TS_BUSY)))
1419                 error = EIO;
1420         lwkt_reltoken(&tty_token);
1421         crit_exit();
1422         return (error);
1423 }
1424
1425 /*
1426  * Flush if successfully wait.
1427  */
1428 static int
1429 ttywflush(struct tty *tp)
1430 {
1431         int error;
1432
1433         if ((error = ttywait(tp)) == 0)
1434                 ttyflush(tp, FREAD);
1435         return (error);
1436 }
1437
1438 /*
1439  * Flush tty read and/or write queues, notifying anyone waiting.
1440  */
1441 void
1442 ttyflush(struct tty *tp, int rw)
1443 {
1444         crit_enter();
1445         lwkt_gettoken(&tty_token);
1446 #if 0
1447 again:
1448 #endif
1449         if (rw & FWRITE) {
1450                 FLUSHQ(&tp->t_outq);
1451                 CLR(tp->t_state, TS_TTSTOP);
1452         }
1453         (*tp->t_stop)(tp, rw);
1454         if (rw & FREAD) {
1455                 FLUSHQ(&tp->t_canq);
1456                 FLUSHQ(&tp->t_rawq);
1457                 CLR(tp->t_lflag, PENDIN);
1458                 tp->t_rocount = 0;
1459                 tp->t_rocol = 0;
1460                 CLR(tp->t_state, TS_LOCAL);
1461                 ttwakeup(tp);
1462                 if (ISSET(tp->t_state, TS_TBLOCK)) {
1463                         if (rw & FWRITE)
1464                                 FLUSHQ(&tp->t_outq);
1465                         ttyunblock(tp);
1466
1467                         /*
1468                          * Don't let leave any state that might clobber the
1469                          * next line discipline (although we should do more
1470                          * to send the START char).  Not clearing the state
1471                          * may have caused the "putc to a clist with no
1472                          * reserved cblocks" panic/kprintf.
1473                          */
1474                         CLR(tp->t_state, TS_TBLOCK);
1475
1476 #if 0 /* forget it, sleeping isn't always safe and we don't know when it is */
1477                         if (ISSET(tp->t_iflag, IXOFF)) {
1478                                 /*
1479                                  * XXX wait a bit in the hope that the stop
1480                                  * character (if any) will go out.  Waiting
1481                                  * isn't good since it allows races.  This
1482                                  * will be fixed when the stop character is
1483                                  * put in a special queue.  Don't bother with
1484                                  * the checks in ttywait() since the timeout
1485                                  * will save us.
1486                                  */
1487                                 SET(tp->t_state, TS_SO_OCOMPLETE);
1488                                 ttysleep(tp, TSA_OCOMPLETE(tp), 0,
1489                                          "ttyfls", hz / 10);
1490                                 /*
1491                                  * Don't try sending the stop character again.
1492                                  */
1493                                 CLR(tp->t_state, TS_TBLOCK);
1494                                 goto again;
1495                         }
1496 #endif
1497                 }
1498         }
1499         if (rw & FWRITE) {
1500                 FLUSHQ(&tp->t_outq);
1501                 ttwwakeup(tp);
1502         }
1503         lwkt_reltoken(&tty_token);
1504         crit_exit();
1505 }
1506
1507 /*
1508  * Copy in the default termios characters.
1509  */
1510 void
1511 termioschars(struct termios *t)
1512 {
1513         lwkt_gettoken(&tty_token);
1514         bcopy(ttydefchars, t->c_cc, sizeof t->c_cc);
1515         lwkt_reltoken(&tty_token);
1516 }
1517
1518 /*
1519  * Old interface.
1520  */
1521 void
1522 ttychars(struct tty *tp)
1523 {
1524         lwkt_gettoken(&tty_token);
1525         termioschars(&tp->t_termios);
1526         lwkt_reltoken(&tty_token);
1527 }
1528
1529 /*
1530  * Handle input high water.  Send stop character for the IXOFF case.  Turn
1531  * on our input flow control bit and propagate the changes to the driver.
1532  * XXX the stop character should be put in a special high priority queue.
1533  */
1534 void
1535 ttyblock(struct tty *tp)
1536 {
1537         lwkt_gettoken(&tty_token);
1538         SET(tp->t_state, TS_TBLOCK);
1539         if (ISSET(tp->t_iflag, IXOFF) && tp->t_cc[VSTOP] != _POSIX_VDISABLE &&
1540             clist_putc(tp->t_cc[VSTOP], &tp->t_outq) != 0)
1541                 CLR(tp->t_state, TS_TBLOCK);    /* try again later */
1542         ttstart(tp);
1543         lwkt_reltoken(&tty_token);
1544 }
1545
1546 /*
1547  * Handle input low water.  Send start character for the IXOFF case.  Turn
1548  * off our input flow control bit and propagate the changes to the driver.
1549  * XXX the start character should be put in a special high priority queue.
1550  */
1551 static void
1552 ttyunblock(struct tty *tp)
1553 {
1554         lwkt_gettoken(&tty_token);
1555         CLR(tp->t_state, TS_TBLOCK);
1556         if (ISSET(tp->t_iflag, IXOFF) && tp->t_cc[VSTART] != _POSIX_VDISABLE &&
1557             clist_putc(tp->t_cc[VSTART], &tp->t_outq) != 0)
1558                 SET(tp->t_state, TS_TBLOCK);    /* try again later */
1559         ttstart(tp);
1560         lwkt_reltoken(&tty_token);
1561 }
1562
1563 int
1564 ttstart(struct tty *tp)
1565 {
1566         lwkt_gettoken(&tty_token);
1567         if (tp->t_oproc != NULL)        /* XXX: Kludge for pty. */
1568                 (*tp->t_oproc)(tp);
1569         lwkt_reltoken(&tty_token);
1570         return (0);
1571 }
1572
1573 /*
1574  * "close" a line discipline
1575  */
1576 int
1577 ttylclose(struct tty *tp, int flag)
1578 {
1579         lwkt_gettoken(&tty_token);
1580         if (flag & FNONBLOCK || ttywflush(tp))
1581                 ttyflush(tp, FREAD | FWRITE);
1582         lwkt_reltoken(&tty_token);
1583         return (0);
1584 }
1585
1586 void
1587 ttyhold(struct tty *tp)
1588 {
1589         ++tp->t_refs;
1590 }
1591
1592 void
1593 ttyunhold(struct tty *tp)
1594 {
1595         if (tp->t_unhold)
1596                 tp->t_unhold(tp);
1597         else
1598                 --tp->t_refs;
1599 }
1600
1601 /*
1602  * Handle modem control transition on a tty.
1603  * Flag indicates new state of carrier.
1604  * Returns 0 if the line should be turned off, otherwise 1.
1605  */
1606 int
1607 ttymodem(struct tty *tp, int flag)
1608 {
1609         lwkt_gettoken(&tty_token);
1610         if (ISSET(tp->t_state, TS_CARR_ON) && ISSET(tp->t_cflag, MDMBUF)) {
1611                 /*
1612                  * MDMBUF: do flow control according to carrier flag
1613                  * XXX TS_CAR_OFLOW doesn't do anything yet.  TS_TTSTOP
1614                  * works if IXON and IXANY are clear.
1615                  */
1616                 if (flag) {
1617                         CLR(tp->t_state, TS_CAR_OFLOW);
1618                         CLR(tp->t_state, TS_TTSTOP);
1619                         ttstart(tp);
1620                 } else if (!ISSET(tp->t_state, TS_CAR_OFLOW)) {
1621                         SET(tp->t_state, TS_CAR_OFLOW);
1622                         SET(tp->t_state, TS_TTSTOP);
1623                         (*tp->t_stop)(tp, 0);
1624                 }
1625         } else if (flag == 0) {
1626                 /*
1627                  * Lost carrier.
1628                  */
1629                 CLR(tp->t_state, TS_CARR_ON);
1630                 if (ISSET(tp->t_state, TS_ISOPEN) &&
1631                     !ISSET(tp->t_cflag, CLOCAL)) {
1632                         SET(tp->t_state, TS_ZOMBIE);
1633                         CLR(tp->t_state, TS_CONNECTED);
1634                         if (tp->t_session && tp->t_session->s_leader)
1635                                 ksignal(tp->t_session->s_leader, SIGHUP);
1636                         ttyflush(tp, FREAD | FWRITE);
1637                         lwkt_reltoken(&tty_token);
1638                         return (0);
1639                 }
1640         } else {
1641                 /*
1642                  * Carrier now on.
1643                  */
1644                 SET(tp->t_state, TS_CARR_ON);
1645                 if (!ISSET(tp->t_state, TS_ZOMBIE))
1646                         SET(tp->t_state, TS_CONNECTED);
1647                 wakeup(TSA_CARR_ON(tp));
1648                 ttwakeup(tp);
1649                 ttwwakeup(tp);
1650         }
1651         lwkt_reltoken(&tty_token);
1652         return (1);
1653 }
1654
1655 /*
1656  * Reinput pending characters after state switch
1657  * call from a critical section.
1658  */
1659 static void
1660 ttypend(struct tty *tp)
1661 {
1662         struct clist tq;
1663         int c;
1664
1665         lwkt_gettoken(&tty_token);
1666         CLR(tp->t_lflag, PENDIN);
1667         SET(tp->t_state, TS_TYPEN);
1668         /*
1669          * XXX this assumes too much about clist internals.  It may even
1670          * fail if the cblock slush pool is empty.  We can't allocate more
1671          * cblocks here because we are called from an interrupt handler
1672          * and clist_alloc_cblocks() can wait.
1673          */
1674         tq = tp->t_rawq;
1675         bzero(&tp->t_rawq, sizeof tp->t_rawq);
1676         tp->t_rawq.c_cbmax = tq.c_cbmax;
1677         tp->t_rawq.c_cbreserved = tq.c_cbreserved;
1678         while ((c = clist_getc(&tq)) >= 0)
1679                 ttyinput(c, tp);
1680         CLR(tp->t_state, TS_TYPEN);
1681         lwkt_reltoken(&tty_token);
1682 }
1683
1684 /*
1685  * Process a read call on a tty device.
1686  */
1687 int
1688 ttread(struct tty *tp, struct uio *uio, int flag)
1689 {
1690         struct clist *qp;
1691         int c;
1692         tcflag_t lflag;
1693         cc_t *cc = tp->t_cc;
1694         struct proc *pp;
1695         struct lwp *lp;
1696         int first, error = 0;
1697         int has_stime = 0, last_cc = 0;
1698         long slp = 0;           /* XXX this should be renamed `timo'. */
1699         struct timeval stime;
1700
1701         lp = curthread->td_lwp;
1702         stime.tv_sec = 0;       /* fix compiler warnings */
1703         stime.tv_usec = 0;
1704
1705         lwkt_gettoken(&tty_token);
1706 loop:
1707         crit_enter();
1708         lflag = tp->t_lflag;
1709         /*
1710          * take pending input first
1711          */
1712         if (ISSET(lflag, PENDIN)) {
1713                 ttypend(tp);
1714                 splz();         /* reduce latency */
1715                 lflag = tp->t_lflag;    /* XXX ttypend() clobbers it */
1716         }
1717
1718         /*
1719          * Hang process if it's in the background.
1720          */
1721         if ((pp = curproc) != NULL)
1722                 lwkt_gettoken(&pp->p_token);
1723         if (pp && isbackground(pp, tp)) {
1724                 crit_exit();
1725                 if (SIGISMEMBER(pp->p_sigignore, SIGTTIN) ||
1726                     SIGISMEMBER(lp->lwp_sigmask, SIGTTIN) ||
1727                     (pp->p_flags & P_PPWAIT) || pp->p_pgrp->pg_jobc == 0) {
1728                         lwkt_reltoken(&pp->p_token);
1729                         lwkt_reltoken(&tty_token);
1730                         return (EIO);
1731                 }
1732                 pgsignal(pp->p_pgrp, SIGTTIN, 1);
1733                 error = ttysleep(tp, &lbolt, PCATCH, "ttybg2", 0);
1734                 if (error) {
1735                         lwkt_reltoken(&pp->p_token);
1736                         lwkt_reltoken(&tty_token);
1737                         return (error);
1738                 }
1739                 lwkt_reltoken(&pp->p_token);
1740                 goto loop;
1741         }
1742         if (pp)
1743                 lwkt_reltoken(&pp->p_token);
1744
1745         if (ISSET(tp->t_state, TS_ZOMBIE)) {
1746                 crit_exit();
1747                 lwkt_reltoken(&tty_token);
1748                 return (0);     /* EOF */
1749         }
1750
1751         /*
1752          * If canonical, use the canonical queue,
1753          * else use the raw queue.
1754          *
1755          * (should get rid of clists...)
1756          */
1757         qp = ISSET(lflag, ICANON) ? &tp->t_canq : &tp->t_rawq;
1758
1759         if (flag & IO_NDELAY) {
1760                 if (qp->c_cc > 0)
1761                         goto read;
1762                 if (!ISSET(lflag, ICANON) && cc[VMIN] == 0) {
1763                         crit_exit();
1764                         lwkt_reltoken(&tty_token);
1765                         return (0);
1766                 }
1767                 crit_exit();
1768                 lwkt_reltoken(&tty_token);
1769                 return (EWOULDBLOCK);
1770         }
1771         if (!ISSET(lflag, ICANON)) {
1772                 int m = cc[VMIN];
1773                 long t = cc[VTIME];
1774                 struct timeval timecopy;
1775
1776                 /*
1777                  * Check each of the four combinations.
1778                  * (m > 0 && t == 0) is the normal read case.
1779                  * It should be fairly efficient, so we check that and its
1780                  * companion case (m == 0 && t == 0) first.
1781                  * For the other two cases, we compute the target sleep time
1782                  * into slp.
1783                  */
1784                 if (t == 0) {
1785                         if (qp->c_cc < m)
1786                                 goto sleep;
1787                         if (qp->c_cc > 0)
1788                                 goto read;
1789
1790                         /* m, t and qp->c_cc are all 0.  0 is enough input. */
1791                         crit_exit();
1792                         lwkt_reltoken(&tty_token);
1793                         return (0);
1794                 }
1795                 t *= 100000;            /* time in us */
1796 #define diff(t1, t2) (((t1).tv_sec - (t2).tv_sec) * 1000000 + \
1797                          ((t1).tv_usec - (t2).tv_usec))
1798                 if (m > 0) {
1799                         if (qp->c_cc <= 0)
1800                                 goto sleep;
1801                         if (qp->c_cc >= m)
1802                                 goto read;
1803                         getmicrotime(&timecopy);
1804                         if (has_stime == 0) {
1805                                 /* first character, start timer */
1806                                 has_stime = 1;
1807                                 stime = timecopy;
1808                                 slp = t;
1809                         } else if (qp->c_cc > last_cc) {
1810                                 /* got a character, restart timer */
1811                                 stime = timecopy;
1812                                 slp = t;
1813                         } else {
1814                                 /* nothing, check expiration */
1815                                 slp = t - diff(timecopy, stime);
1816                                 if (slp <= 0)
1817                                         goto read;
1818                         }
1819                         last_cc = qp->c_cc;
1820                 } else {        /* m == 0 */
1821                         if (qp->c_cc > 0)
1822                                 goto read;
1823                         getmicrotime(&timecopy);
1824                         if (has_stime == 0) {
1825                                 has_stime = 1;
1826                                 stime = timecopy;
1827                                 slp = t;
1828                         } else {
1829                                 slp = t - diff(timecopy, stime);
1830                                 if (slp <= 0) {
1831                                         /* Timed out, but 0 is enough input. */
1832                                         crit_exit();
1833                                         lwkt_reltoken(&tty_token);
1834                                         return (0);
1835                                 }
1836                         }
1837                 }
1838 #undef diff
1839                 /*
1840                  * Rounding down may make us wake up just short
1841                  * of the target, so we round up.
1842                  * The formula is ceiling(slp * hz/1000000).
1843                  * 32-bit arithmetic is enough for hz < 169.
1844                  * XXX see tvtohz() for how to avoid overflow if hz
1845                  * is large (divide by `tick' and/or arrange to
1846                  * use tvtohz() if hz is large).
1847                  */
1848                 slp = (long) (((u_long)slp * hz) + 999999) / 1000000;
1849                 goto sleep;
1850         }
1851         if (qp->c_cc <= 0) {
1852 sleep:
1853                 /*
1854                  * There is no input, or not enough input and we can block.
1855                  */
1856                 error = ttysleep(tp, TSA_HUP_OR_INPUT(tp), PCATCH,
1857                                  ISSET(tp->t_state, TS_CONNECTED) ?
1858                                  "ttyin" : "ttyhup", (int)slp);
1859                 crit_exit();
1860                 if (error == EWOULDBLOCK)
1861                         error = 0;
1862                 else if (error) {
1863                         lwkt_reltoken(&tty_token);
1864                         return (error);
1865                 }
1866                 /*
1867                  * XXX what happens if another process eats some input
1868                  * while we are asleep (not just here)?  It would be
1869                  * safest to detect changes and reset our state variables
1870                  * (has_stime and last_cc).
1871                  */
1872                 slp = 0;
1873                 goto loop;
1874         }
1875 read:
1876         crit_exit();
1877         /*
1878          * Input present, check for input mapping and processing.
1879          */
1880         first = 1;
1881         if (ISSET(lflag, ICANON | ISIG))
1882                 goto slowcase;
1883         for (;;) {
1884                 char ibuf[IBUFSIZ];
1885                 int icc;
1886
1887                 icc = (int)szmin(uio->uio_resid, IBUFSIZ);
1888                 icc = q_to_b(qp, ibuf, icc);
1889                 if (icc <= 0) {
1890                         if (first)
1891                                 goto loop;
1892                         break;
1893                 }
1894                 error = uiomove(ibuf, (size_t)icc, uio);
1895                 /*
1896                  * XXX if there was an error then we should ungetc() the
1897                  * unmoved chars and reduce icc here.
1898                  */
1899                 if (error)
1900                         break;
1901                 if (uio->uio_resid == 0)
1902                         break;
1903                 first = 0;
1904         }
1905         goto out;
1906 slowcase:
1907         for (;;) {
1908                 c = clist_getc(qp);
1909                 if (c < 0) {
1910                         if (first)
1911                                 goto loop;
1912                         break;
1913                 }
1914                 /*
1915                  * delayed suspend (^Y)
1916                  */
1917                 if (CCEQ(cc[VDSUSP], c) &&
1918                     ISSET(lflag, IEXTEN | ISIG) == (IEXTEN | ISIG)) {
1919                         pgsignal(tp->t_pgrp, SIGTSTP, 1);
1920                         if (first) {
1921                                 error = ttysleep(tp, &lbolt, PCATCH,
1922                                                  "ttybg3", 0);
1923                                 if (error)
1924                                         break;
1925                                 goto loop;
1926                         }
1927                         break;
1928                 }
1929                 /*
1930                  * Interpret EOF only in canonical mode.
1931                  */
1932                 if (CCEQ(cc[VEOF], c) && ISSET(lflag, ICANON))
1933                         break;
1934                 /*
1935                  * Give user character.
1936                  */
1937                 error = ureadc(c, uio);
1938                 if (error)
1939                         /* XXX should ungetc(c, qp). */
1940                         break;
1941                 if (uio->uio_resid == 0)
1942                         break;
1943                 /*
1944                  * In canonical mode check for a "break character"
1945                  * marking the end of a "line of input".
1946                  */
1947                 if (ISSET(lflag, ICANON) && TTBREAKC(c, lflag))
1948                         break;
1949                 first = 0;
1950         }
1951
1952 out:
1953         /*
1954          * Look to unblock input now that (presumably)
1955          * the input queue has gone down.
1956          */
1957         crit_enter();
1958         if (ISSET(tp->t_state, TS_TBLOCK) &&
1959             tp->t_rawq.c_cc + tp->t_canq.c_cc <= tp->t_ilowat)
1960                 ttyunblock(tp);
1961         crit_exit();
1962
1963         lwkt_reltoken(&tty_token);
1964         return (error);
1965 }
1966
1967 /*
1968  * Check the output queue on tp for space for a kernel message (from uprintf
1969  * or tprintf).  Allow some space over the normal hiwater mark so we don't
1970  * lose messages due to normal flow control, but don't let the tty run amok.
1971  * Sleeps here are not interruptible, but we return prematurely if new signals
1972  * arrive.
1973  */
1974 int
1975 ttycheckoutq(struct tty *tp, int wait)
1976 {
1977         struct lwp *lp = curthread->td_lwp;
1978         int hiwat;
1979         sigset_t oldset, newset;
1980
1981         lwkt_gettoken(&tty_token);
1982         hiwat = tp->t_ohiwat;
1983         SIGEMPTYSET(oldset);
1984         SIGEMPTYSET(newset);
1985         crit_enter();
1986         if (wait)
1987                 oldset = lwp_sigpend(lp);
1988         if (tp->t_outq.c_cc > hiwat + OBUFSIZ + 100) {
1989                 while (tp->t_outq.c_cc > hiwat) {
1990                         ttstart(tp);
1991                         if (tp->t_outq.c_cc <= hiwat)
1992                                 break;
1993                         if (wait)
1994                                 newset = lwp_sigpend(lp);
1995                         if (!wait || SIGSETNEQ(oldset, newset)) {
1996                                 crit_exit();
1997                                 lwkt_reltoken(&tty_token);
1998                                 return (0);
1999                         }
2000                         SET(tp->t_state, TS_SO_OLOWAT);
2001                         tsleep(TSA_OLOWAT(tp), 0, "ttoutq", hz);
2002                 }
2003         }
2004         crit_exit();
2005         lwkt_reltoken(&tty_token);
2006         return (1);
2007 }
2008
2009 /*
2010  * Process a write call on a tty device.
2011  */
2012 int
2013 ttwrite(struct tty *tp, struct uio *uio, int flag)
2014 {
2015         char *cp = NULL;
2016         int cc, ce;
2017         struct proc *pp;
2018         struct lwp *lp;
2019         int i, hiwat, error;
2020         size_t cnt;
2021
2022         char obuf[OBUFSIZ];
2023
2024         lwkt_gettoken(&tty_token);
2025         lp = curthread->td_lwp;
2026         hiwat = tp->t_ohiwat;
2027         cnt = uio->uio_resid;
2028         error = 0;
2029         cc = 0;
2030 loop:
2031         crit_enter();
2032         if (ISSET(tp->t_state, TS_ZOMBIE)) {
2033                 crit_exit();
2034                 if (uio->uio_resid == cnt)
2035                         error = EIO;
2036                 goto out;
2037         }
2038         if (!ISSET(tp->t_state, TS_CONNECTED)) {
2039                 if (flag & IO_NDELAY) {
2040                         crit_exit();
2041                         error = EWOULDBLOCK;
2042                         goto out;
2043                 }
2044                 error = ttysleep(tp, TSA_CARR_ON(tp), PCATCH, "ttydcd", 0);
2045                 crit_exit();
2046                 if (error)
2047                         goto out;
2048                 goto loop;
2049         }
2050         crit_exit();
2051
2052         /*
2053          * Hang the process if it's in the background.
2054          */
2055         if ((pp = curproc) != NULL)
2056                 lwkt_gettoken(&pp->p_token);
2057         if (pp && isbackground(pp, tp) &&
2058             ISSET(tp->t_lflag, TOSTOP) && !(pp->p_flags & P_PPWAIT) &&
2059             !SIGISMEMBER(pp->p_sigignore, SIGTTOU) &&
2060             !SIGISMEMBER(lp->lwp_sigmask, SIGTTOU)) {
2061                 if (pp->p_pgrp->pg_jobc == 0) {
2062                         error = EIO;
2063                         lwkt_reltoken(&pp->p_token);
2064                         goto out;
2065                 }
2066                 pgsignal(pp->p_pgrp, SIGTTOU, 1);
2067                 lwkt_reltoken(&pp->p_token);
2068                 error = ttysleep(tp, &lbolt, PCATCH, "ttybg4", 0);
2069                 if (error)
2070                         goto out;
2071                 goto loop;
2072         }
2073         if (pp)
2074                 lwkt_reltoken(&pp->p_token);
2075         /*
2076          * Process the user's data in at most OBUFSIZ chunks.  Perform any
2077          * output translation.  Keep track of high water mark, sleep on
2078          * overflow awaiting device aid in acquiring new space.
2079          */
2080         while (uio->uio_resid > 0 || cc > 0) {
2081                 if (ISSET(tp->t_lflag, FLUSHO)) {
2082                         uio->uio_resid = 0;
2083                         lwkt_reltoken(&tty_token);
2084                         return (0);
2085                 }
2086                 if (tp->t_outq.c_cc > hiwat)
2087                         goto ovhiwat;
2088                 /*
2089                  * Grab a hunk of data from the user, unless we have some
2090                  * leftover from last time.
2091                  */
2092                 if (cc == 0) {
2093                         cc = szmin(uio->uio_resid, OBUFSIZ);
2094                         cp = obuf;
2095                         error = uiomove(cp, (size_t)cc, uio);
2096                         if (error) {
2097                                 cc = 0;
2098                                 break;
2099                         }
2100                 }
2101                 /*
2102                  * If nothing fancy need be done, grab those characters we
2103                  * can handle without any of ttyoutput's processing and
2104                  * just transfer them to the output q.  For those chars
2105                  * which require special processing (as indicated by the
2106                  * bits in char_type), call ttyoutput.  After processing
2107                  * a hunk of data, look for FLUSHO so ^O's will take effect
2108                  * immediately.
2109                  */
2110                 while (cc > 0) {
2111                         if (!ISSET(tp->t_oflag, OPOST))
2112                                 ce = cc;
2113                         else {
2114                                 ce = cc - scanc((u_int)cc, (u_char *)cp,
2115                                                 char_type, CCLASSMASK);
2116                                 /*
2117                                  * If ce is zero, then we're processing
2118                                  * a special character through ttyoutput.
2119                                  */
2120                                 if (ce == 0) {
2121                                         tp->t_rocount = 0;
2122                                         if (ttyoutput(*cp, tp) >= 0) {
2123                                                 /* No Clists, wait a bit. */
2124                                                 ttstart(tp);
2125                                                 if (flag & IO_NDELAY) {
2126                                                         error = EWOULDBLOCK;
2127                                                         goto out;
2128                                                 }
2129                                                 error = ttysleep(tp, &lbolt,
2130                                                                  PCATCH,
2131                                                                  "ttybf1", 0);
2132                                                 if (error)
2133                                                         goto out;
2134                                                 goto loop;
2135                                         }
2136                                         cp++;
2137                                         cc--;
2138                                         if (ISSET(tp->t_lflag, FLUSHO) ||
2139                                             tp->t_outq.c_cc > hiwat)
2140                                                 goto ovhiwat;
2141                                         continue;
2142                                 }
2143                         }
2144                         /*
2145                          * A bunch of normal characters have been found.
2146                          * Transfer them en masse to the output queue and
2147                          * continue processing at the top of the loop.
2148                          * If there are any further characters in this
2149                          * <= OBUFSIZ chunk, the first should be a character
2150                          * requiring special handling by ttyoutput.
2151                          */
2152                         tp->t_rocount = 0;
2153                         i = b_to_q(cp, ce, &tp->t_outq);
2154                         ce -= i;
2155                         tp->t_column += ce;
2156                         cp += ce, cc -= ce, tk_nout += ce;
2157                         tp->t_outcc += ce;
2158                         if (i > 0) {
2159                                 /* No Clists, wait a bit. */
2160                                 ttstart(tp);
2161                                 if (flag & IO_NDELAY) {
2162                                         error = EWOULDBLOCK;
2163                                         goto out;
2164                                 }
2165                                 error = ttysleep(tp, &lbolt, PCATCH,
2166                                                  "ttybf2", 0);
2167                                 if (error)
2168                                         goto out;
2169                                 goto loop;
2170                         }
2171                         if (ISSET(tp->t_lflag, FLUSHO) ||
2172                             tp->t_outq.c_cc > hiwat)
2173                                 break;
2174                 }
2175                 ttstart(tp);
2176         }
2177 out:
2178         /*
2179          * If cc is nonzero, we leave the uio structure inconsistent, as the
2180          * offset and iov pointers have moved forward, but it doesn't matter
2181          * (the call will either return short or restart with a new uio).
2182          */
2183         uio->uio_resid += cc;
2184         lwkt_reltoken(&tty_token);
2185         return (error);
2186
2187 ovhiwat:
2188         ttstart(tp);
2189         crit_enter();
2190         /*
2191          * This can only occur if FLUSHO is set in t_lflag,
2192          * or if ttstart/oproc is synchronous (or very fast).
2193          */
2194         if (tp->t_outq.c_cc <= hiwat) {
2195                 crit_exit();
2196                 goto loop;
2197         }
2198         if (flag & IO_NDELAY) {
2199                 crit_exit();
2200                 uio->uio_resid += cc;
2201                 lwkt_reltoken(&tty_token);
2202                 return (uio->uio_resid == cnt ? EWOULDBLOCK : 0);
2203         }
2204         SET(tp->t_state, TS_SO_OLOWAT);
2205         error = ttysleep(tp, TSA_OLOWAT(tp), PCATCH, "ttywri", tp->t_timeout);
2206         crit_exit();
2207         if (error == EWOULDBLOCK)
2208                 error = EIO;
2209         if (error)
2210                 goto out;
2211         goto loop;
2212 }
2213
2214 /*
2215  * Rubout one character from the rawq of tp
2216  * as cleanly as possible.
2217  * NOTE: Must be called with tty_token held
2218  */
2219 static void
2220 ttyrub(int c, struct tty *tp)
2221 {
2222         char *cp;
2223         int savecol;
2224         int tabc;
2225
2226         ASSERT_LWKT_TOKEN_HELD(&tty_token);
2227         if (!ISSET(tp->t_lflag, ECHO) || ISSET(tp->t_lflag, EXTPROC))
2228                 return;
2229         CLR(tp->t_lflag, FLUSHO);
2230         if (ISSET(tp->t_lflag, ECHOE)) {
2231                 if (tp->t_rocount == 0) {
2232                         /*
2233                          * Screwed by ttwrite; retype
2234                          */
2235                         ttyretype(tp);
2236                         return;
2237                 }
2238                 if (c == ('\t' | TTY_QUOTE) || c == ('\n' | TTY_QUOTE))
2239                         ttyrubo(tp, 2);
2240                 else {
2241                         CLR(c, ~TTY_CHARMASK);
2242                         switch (CCLASS(c)) {
2243                         case ORDINARY:
2244                                 ttyrubo(tp, 1);
2245                                 break;
2246                         case BACKSPACE:
2247                         case CONTROL:
2248                         case NEWLINE:
2249                         case RETURN:
2250                         case VTAB:
2251                                 if (ISSET(tp->t_lflag, ECHOCTL))
2252                                         ttyrubo(tp, 2);
2253                                 break;
2254                         case TAB:
2255                                 if (tp->t_rocount < tp->t_rawq.c_cc) {
2256                                         ttyretype(tp);
2257                                         return;
2258                                 }
2259                                 crit_enter();
2260                                 savecol = tp->t_column;
2261                                 SET(tp->t_state, TS_CNTTB);
2262                                 SET(tp->t_lflag, FLUSHO);
2263                                 tp->t_column = tp->t_rocol;
2264                                 cp = tp->t_rawq.c_cf;
2265                                 if (cp)
2266                                         tabc = *cp;     /* XXX FIX NEXTC */
2267                                 for (; cp; cp = nextc(&tp->t_rawq, cp, &tabc))
2268                                         ttyecho(tabc, tp);
2269                                 CLR(tp->t_lflag, FLUSHO);
2270                                 CLR(tp->t_state, TS_CNTTB);
2271                                 crit_exit();
2272
2273                                 /* savecol will now be length of the tab. */
2274                                 savecol -= tp->t_column;
2275                                 tp->t_column += savecol;
2276                                 if (savecol > 8)
2277                                         savecol = 8;    /* overflow screw */
2278                                 while (--savecol >= 0)
2279                                         (void)ttyoutput('\b', tp);
2280                                 break;
2281                         default:                        /* XXX */
2282 #define PANICSTR        "ttyrub: would panic c = %d, val = %d\n"
2283                                 (void)kprintf(PANICSTR, c, CCLASS(c));
2284 #ifdef notdef
2285                                 panic(PANICSTR, c, CCLASS(c));
2286 #endif
2287                         }
2288                 }
2289         } else if (ISSET(tp->t_lflag, ECHOPRT)) {
2290                 if (!ISSET(tp->t_state, TS_ERASE)) {
2291                         SET(tp->t_state, TS_ERASE);
2292                         (void)ttyoutput('\\', tp);
2293                 }
2294                 ttyecho(c, tp);
2295         } else {
2296                 ttyecho(tp->t_cc[VERASE], tp);
2297                 /*
2298                  * This code may be executed not only when an ERASE key
2299                  * is pressed, but also when ^U (KILL) or ^W (WERASE) are.
2300                  * So, I didn't think it was worthwhile to pass the extra
2301                  * information (which would need an extra parameter,
2302                  * changing every call) needed to distinguish the ERASE2
2303                  * case from the ERASE.
2304                  */
2305         }
2306         --tp->t_rocount;
2307 }
2308
2309 /*
2310  * Back over cnt characters, erasing them.
2311  * NOTE: Must be called with tty_token held
2312  */
2313 static void
2314 ttyrubo(struct tty *tp, int cnt)
2315 {
2316         ASSERT_LWKT_TOKEN_HELD(&tty_token);
2317         while (cnt-- > 0) {
2318                 (void)ttyoutput('\b', tp);
2319                 (void)ttyoutput(' ', tp);
2320                 (void)ttyoutput('\b', tp);
2321         }
2322 }
2323
2324 /*
2325  * ttyretype --
2326  *      Reprint the rawq line.  Note, it is assumed that c_cc has already
2327  *      been checked.
2328  * NOTE: Must be called with tty_token held
2329  */
2330 static void
2331 ttyretype(struct tty *tp)
2332 {
2333         char *cp;
2334         int c;
2335
2336         ASSERT_LWKT_TOKEN_HELD(&tty_token);
2337         /* Echo the reprint character. */
2338         if (tp->t_cc[VREPRINT] != _POSIX_VDISABLE)
2339                 ttyecho(tp->t_cc[VREPRINT], tp);
2340
2341         (void)ttyoutput('\n', tp);
2342
2343         /*
2344          * XXX
2345          * FIX: NEXTC IS BROKEN - DOESN'T CHECK QUOTE
2346          * BIT OF FIRST CHAR.
2347          */
2348         crit_enter();
2349         for (cp = tp->t_canq.c_cf, c = (cp != NULL ? *cp : 0);
2350             cp != NULL; cp = nextc(&tp->t_canq, cp, &c))
2351                 ttyecho(c, tp);
2352         for (cp = tp->t_rawq.c_cf, c = (cp != NULL ? *cp : 0);
2353             cp != NULL; cp = nextc(&tp->t_rawq, cp, &c))
2354                 ttyecho(c, tp);
2355         CLR(tp->t_state, TS_ERASE);
2356         crit_exit();
2357
2358         tp->t_rocount = tp->t_rawq.c_cc;
2359         tp->t_rocol = 0;
2360 }
2361
2362 /*
2363  * Echo a typed character to the terminal.
2364  * NOTE: Must be called with tty_token held
2365  */
2366 static void
2367 ttyecho(int c, struct tty *tp)
2368 {
2369         ASSERT_LWKT_TOKEN_HELD(&tty_token);
2370
2371         if (!ISSET(tp->t_state, TS_CNTTB))
2372                 CLR(tp->t_lflag, FLUSHO);
2373         if ((!ISSET(tp->t_lflag, ECHO) &&
2374              (c != '\n' || !ISSET(tp->t_lflag, ECHONL))) ||
2375             ISSET(tp->t_lflag, EXTPROC))
2376                 return;
2377         if (ISSET(tp->t_lflag, ECHOCTL) &&
2378             ((ISSET(c, TTY_CHARMASK) <= 037 && c != '\t' && c != '\n') ||
2379             ISSET(c, TTY_CHARMASK) == 0177)) {
2380                 (void)ttyoutput('^', tp);
2381                 CLR(c, ~TTY_CHARMASK);
2382                 if (c == 0177)
2383                         c = '?';
2384                 else
2385                         c += 'A' - 1;
2386         }
2387         (void)ttyoutput(c, tp);
2388 }
2389
2390 /*
2391  * Wake up any readers on a tty.
2392  */
2393 void
2394 ttwakeup(struct tty *tp)
2395 {
2396         lwkt_gettoken(&tty_token);
2397         if (ISSET(tp->t_state, TS_ASYNC) && tp->t_sigio != NULL)
2398                 pgsigio(tp->t_sigio, SIGIO, (tp->t_session != NULL));
2399         wakeup(TSA_HUP_OR_INPUT(tp));
2400         KNOTE(&tp->t_rkq.ki_note, 0);
2401         lwkt_reltoken(&tty_token);
2402 }
2403
2404 /*
2405  * Wake up any writers on a tty.
2406  */
2407 void
2408 ttwwakeup(struct tty *tp)
2409 {
2410         lwkt_gettoken(&tty_token);
2411         if (ISSET(tp->t_state, TS_ASYNC) && tp->t_sigio != NULL)
2412                 pgsigio(tp->t_sigio, SIGIO, (tp->t_session != NULL));
2413         if (ISSET(tp->t_state, TS_BUSY | TS_SO_OCOMPLETE) ==
2414             TS_SO_OCOMPLETE && tp->t_outq.c_cc == 0) {
2415                 CLR(tp->t_state, TS_SO_OCOMPLETE);
2416                 wakeup(TSA_OCOMPLETE(tp));
2417         }
2418         if (ISSET(tp->t_state, TS_SO_OLOWAT) &&
2419             tp->t_outq.c_cc <= tp->t_olowat) {
2420                 CLR(tp->t_state, TS_SO_OLOWAT);
2421                 wakeup(TSA_OLOWAT(tp));
2422         }
2423         KNOTE(&tp->t_wkq.ki_note, 0);
2424         lwkt_reltoken(&tty_token);
2425 }
2426
2427 /*
2428  * Look up a code for a specified speed in a conversion table;
2429  * used by drivers to map software speed values to hardware parameters.
2430  * No requirements
2431  */
2432 int
2433 ttspeedtab(int speed, struct speedtab *table)
2434 {
2435
2436         for ( ; table->sp_speed != -1; table++)
2437                 if (table->sp_speed == speed)
2438                         return (table->sp_code);
2439         return (-1);
2440 }
2441
2442 /*
2443  * Set input and output watermarks and buffer sizes.  For input, the
2444  * high watermark is about one second's worth of input above empty, the
2445  * low watermark is slightly below high water, and the buffer size is a
2446  * driver-dependent amount above high water.  For output, the watermarks
2447  * are near the ends of the buffer, with about 1 second's worth of input
2448  * between them.  All this only applies to the standard line discipline.
2449  */
2450 void
2451 ttsetwater(struct tty *tp)
2452 {
2453         int cps, ttmaxhiwat, x;
2454
2455         lwkt_gettoken(&tty_token);
2456         /* Input. */
2457         clist_alloc_cblocks(&tp->t_canq, TTYHOG, 512);
2458         switch (tp->t_ispeedwat) {
2459         case (speed_t)-1:
2460                 cps = tp->t_ispeed / 10;
2461                 break;
2462         case 0:
2463                 /*
2464                  * This case is for old drivers that don't know about
2465                  * t_ispeedwat.  Arrange for them to get the old buffer
2466                  * sizes and watermarks.
2467                  */
2468                 cps = TTYHOG - 2 * 256;
2469                 tp->t_ififosize = 2 * 2048;
2470                 break;
2471         default:
2472                 cps = tp->t_ispeedwat / 10;
2473                 break;
2474         }
2475         tp->t_ihiwat = cps;
2476         tp->t_ilowat = 7 * cps / 8;
2477         x = cps + tp->t_ififosize;
2478         clist_alloc_cblocks(&tp->t_rawq, x, x);
2479
2480         /* Output. */
2481         switch (tp->t_ospeedwat) {
2482         case (speed_t)-1:
2483                 cps = tp->t_ospeed / 10;
2484                 ttmaxhiwat = 2 * TTMAXHIWAT;
2485                 break;
2486         case 0:
2487                 cps = tp->t_ospeed / 10;
2488                 ttmaxhiwat = TTMAXHIWAT;
2489                 break;
2490         default:
2491                 cps = tp->t_ospeedwat / 10;
2492                 ttmaxhiwat = 8 * TTMAXHIWAT;
2493                 break;
2494         }
2495 #define CLAMP(x, h, l)  ((x) > h ? h : ((x) < l) ? l : (x))
2496         tp->t_olowat = x = CLAMP(cps / 2, TTMAXLOWAT, TTMINLOWAT);
2497         x += cps;
2498         x = CLAMP(x, ttmaxhiwat, TTMINHIWAT);   /* XXX clamps are too magic */
2499         tp->t_ohiwat = roundup(x, CBSIZE);      /* XXX for compat */
2500         x = imax(tp->t_ohiwat, TTMAXHIWAT);     /* XXX for compat/safety */
2501         x += OBUFSIZ + 100;
2502         clist_alloc_cblocks(&tp->t_outq, x, x);
2503 #undef  CLAMP
2504         lwkt_reltoken(&tty_token);
2505 }
2506
2507 /*
2508  * Report on state of foreground process group.
2509  */
2510 void
2511 ttyinfo(struct tty *tp)
2512 {
2513         struct pgrp *pgrp;
2514         struct proc *p, *pick;
2515         struct lwp *lp;
2516         struct rusage ru;
2517         char buf[64];
2518         const char *str;
2519         struct vmspace *vm;
2520         long vmsz;
2521         int pctcpu;
2522         int tmp;
2523
2524         if (ttycheckoutq(tp,0) == 0)
2525                 return;
2526
2527         lwkt_gettoken(&tty_token);
2528
2529         /*
2530          * We always print the load average, then figure out what else to
2531          * print based on the state of the current process group.
2532          */
2533         tmp = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT;
2534         ttyprintf(tp, "load: %d.%02d ", tmp / 100, tmp % 100);
2535
2536         if (tp->t_session == NULL) {
2537                 ttyprintf(tp, "not a controlling terminal\n");
2538                 goto done2;
2539         }
2540         if ((pgrp = tp->t_pgrp) == NULL) {
2541                 ttyprintf(tp, "no foreground process group\n");
2542                 goto done2;
2543         }
2544
2545         /*
2546          * Pick an interesting process.  Note that certain elements,
2547          * in particular the wmesg, require a critical section for
2548          * safe access (YYY and we are still not MP safe).
2549          *
2550          * NOTE: lwp_wmesg is lwp_thread->td_wmesg.
2551          */
2552         pgref(pgrp);
2553         lwkt_gettoken(&pgrp->pg_token);
2554
2555         pick = NULL;
2556         for (p = LIST_FIRST(&pgrp->pg_members);
2557              p != NULL;
2558              p = LIST_NEXT(p, p_pglist)) {
2559                 PHOLD(p);
2560                 if (proc_compare(pick, p)) {
2561                         if (pick)
2562                                 PRELE(pick);
2563                         pick = p;
2564                 } else {
2565                         PRELE(p);
2566                 }
2567         }
2568         if (pick == NULL) {
2569                 ttyprintf(tp, "empty foreground process group\n");
2570                 goto done1;
2571         }
2572
2573         /*
2574          * Pick an interesting LWP (XXX)
2575          *
2576          * pick is held.
2577          */
2578         lp = FIRST_LWP_IN_PROC(pick);
2579         if (lp == NULL) {
2580                 PRELE(pick);
2581                 ttyprintf(tp, "foreground process without lwp\n");
2582                 goto done1;
2583         }
2584
2585         /*
2586          * Figure out what wait/process-state message, and command
2587          * buffer to present
2588          */
2589         /*
2590          * XXX lwp This is a horrible mixture.  We need to rework this
2591          * as soon as lwps have their own runnable status.
2592          */
2593         LWPHOLD(lp);
2594         if (pick->p_flags & P_WEXIT)
2595                 str = "exiting";
2596         else if (lp->lwp_stat == LSRUN)
2597                 str = "running";
2598         else if (pick->p_stat == SIDL)
2599                 str = "spawning";
2600         else if (lp->lwp_wmesg) /* lwp_thread must not be NULL */
2601                 str = lp->lwp_wmesg;
2602         else
2603                 str = "iowait";
2604
2605         ksnprintf(buf, sizeof(buf), "cmd: %s %d [%s]",
2606                   pick->p_comm, pick->p_pid, str);
2607
2608         /*
2609          * Calculate cpu usage, percent cpu, and cmsz.  Note that
2610          * 'pick' becomes invalid the moment we exit the critical
2611          * section.
2612          */
2613         if (lp->lwp_thread && (pick->p_flags & P_SWAPPEDOUT) == 0)
2614                 calcru_proc(pick, &ru);
2615
2616         pctcpu = (lp->lwp_pctcpu * 10000 + FSCALE / 2) >> FSHIFT;
2617
2618         LWPRELE(lp);
2619
2620         /*
2621          * NOTE: vmspace should be protected from destruction by the
2622          *       combination of pg_token and the fact that we are not
2623          *       flagged as a zombie.
2624          */
2625         if (pick->p_stat == SIDL || pick->p_stat == SZOMB) {
2626                 vmsz = 0;
2627         } else if ((vm = pick->p_vmspace) == NULL) {
2628                 vmsz = 0;
2629         } else {
2630                 vmspace_hold(vm);
2631                 vmsz = pgtok(vmspace_resident_count(vm));
2632                 vmspace_drop(vm);
2633         }
2634         PRELE(pick);
2635
2636         /*
2637          * Dump the output
2638          */
2639         ttyprintf(tp, " %s ",
2640                   buf);
2641         ttyprintf(tp, "%ld.%02ldu ",
2642                   ru.ru_utime.tv_sec, ru.ru_utime.tv_usec / 10000);
2643         ttyprintf(tp, "%ld.%02lds ",
2644                   ru.ru_stime.tv_sec, ru.ru_stime.tv_usec / 10000);
2645         ttyprintf(tp, "%d%% %ldk\n",
2646                   pctcpu / 100, vmsz);
2647
2648 done1:
2649         lwkt_reltoken(&pgrp->pg_token);
2650         pgrel(pgrp);
2651 done2:
2652         tp->t_rocount = 0;      /* so pending input will be retyped if BS */
2653         lwkt_reltoken(&tty_token);
2654 }
2655
2656 /*
2657  * Returns 1 if p2 is "better" than p1
2658  *
2659  * The algorithm for picking the "interesting" process is thus:
2660  *
2661  *      1) Only foreground processes are eligible - implied.
2662  *      2) Runnable processes are favored over anything else.  The runner
2663  *         with the highest cpu utilization is picked (p_cpticks).  Ties are
2664  *         broken by picking the highest pid.
2665  *      3) The sleeper with the shortest sleep time is next.  With ties,
2666  *         we pick out just "short-term" sleepers (LWP_SINTR == 0).
2667  *      4) Further ties are broken by picking the highest pid.
2668  *
2669  * NOTE: must be called with p1 and p2 held.
2670  */
2671 #define ISRUN(lp)       ((lp)->lwp_stat == LSRUN)
2672 #define TESTAB(a, b)    ((a)<<1 | (b))
2673 #define ONLYA   2
2674 #define ONLYB   1
2675 #define BOTH    3
2676
2677 static int
2678 proc_compare(struct proc *p1, struct proc *p2)
2679 {
2680         struct lwp *lp1, *lp2;
2681         int res;
2682
2683         if (p1 == NULL)
2684                 return (1);
2685         if (lwkt_trytoken(&p1->p_token) == 0)
2686                 return (1);
2687         if (lwkt_trytoken(&p2->p_token) == 0) {
2688                 lwkt_reltoken(&p1->p_token);
2689                 return (0);
2690         }
2691
2692         /*
2693          * weed out zombies
2694          */
2695         switch (TESTAB(p1->p_stat == SZOMB, p2->p_stat == SZOMB)) {
2696         case ONLYA:
2697                 res = 1;
2698                 goto done;
2699         case ONLYB:
2700                 res = 0;
2701                 goto done;
2702         case BOTH:
2703                 res = (p2->p_pid > p1->p_pid);  /* tie - return highest pid */
2704                 goto done;
2705         default:
2706                 break;
2707         }
2708
2709         /* XXX choose the best lwp? */
2710         lp1 = FIRST_LWP_IN_PROC(p1);
2711         lp2 = FIRST_LWP_IN_PROC(p2);
2712
2713         /*
2714          * Favor one with LWPs verses one that has none (is exiting).
2715          */
2716         if (lp1 == NULL) {
2717                 res = 1;
2718                 goto done;
2719         }
2720         if (lp2 == NULL) {
2721                 res = 0;
2722                 goto done;
2723         }
2724
2725         /*
2726          * see if at least one of them is runnable
2727          */
2728         switch (TESTAB(ISRUN(lp1), ISRUN(lp2))) {
2729         case ONLYA:
2730                 res = 0;
2731                 goto done;
2732         case ONLYB:
2733                 res = 1;
2734                 goto done;
2735         case BOTH:
2736                 /*
2737                  * tie - favor one with highest recent cpu utilization
2738                  */
2739                 if (lp2->lwp_cpticks > lp1->lwp_cpticks)
2740                         res = 1;
2741                 else if (lp1->lwp_cpticks > lp2->lwp_cpticks)
2742                         res = 0;
2743                 else
2744                         res = (p2->p_pid > p1->p_pid); /* tie - ret highest */
2745                 goto done;
2746         default:
2747                 break;
2748         }
2749
2750         /*
2751          * Pick the one with the smallest sleep time
2752          */
2753         if (lp2->lwp_slptime > lp1->lwp_slptime) {
2754                 res = 0;
2755                 goto done;
2756         }
2757         if (lp1->lwp_slptime > lp2->lwp_slptime) {
2758                 res = 1;
2759                 goto done;
2760         }
2761
2762         /*
2763          * Favor one sleeping in a non-interruptible sleep
2764          */
2765         if ((lp1->lwp_flags & LWP_SINTR) && (lp2->lwp_flags & LWP_SINTR) == 0)
2766                 res = 1;
2767         else
2768         if ((lp2->lwp_flags & LWP_SINTR) && (lp1->lwp_flags & LWP_SINTR) == 0)
2769                 res = 0;
2770         else
2771                 res = (p2->p_pid > p1->p_pid);  /* tie - return highest pid */
2772         /* fall through */
2773
2774 done:
2775         lwkt_reltoken(&p2->p_token);
2776         lwkt_reltoken(&p1->p_token);
2777         return (res);
2778 }
2779
2780 /*
2781  * Output char to tty; console putchar style.
2782  */
2783 int
2784 tputchar(int c, struct tty *tp)
2785 {
2786         crit_enter();
2787         lwkt_gettoken(&tty_token);
2788         if (!ISSET(tp->t_state, TS_CONNECTED)) {
2789                 lwkt_reltoken(&tty_token);
2790                 crit_exit();
2791                 return (-1);
2792         }
2793         if (c == '\n')
2794                 (void)ttyoutput('\r', tp);
2795         (void)ttyoutput(c, tp);
2796         ttstart(tp);
2797         lwkt_reltoken(&tty_token);
2798         crit_exit();
2799         return (0);
2800 }
2801
2802 /*
2803  * Sleep on chan, returning ERESTART if tty changed while we napped and
2804  * returning any errors (e.g. EINTR/EWOULDBLOCK) reported by tsleep.  If
2805  * the tty is revoked, restarting a pending call will redo validation done
2806  * at the start of the call.
2807  */
2808 int
2809 ttysleep(struct tty *tp, void *chan, int slpflags, char *wmesg, int timo)
2810 {
2811         int error;
2812         int gen;
2813
2814         gen = tp->t_gen;
2815         error = tsleep(chan, slpflags, wmesg, timo);
2816         if (error)
2817                 return (error);
2818         return (tp->t_gen == gen ? 0 : ERESTART);
2819 }
2820
2821 /*
2822  * Revoke a tty.
2823  *
2824  * We bump the gen to force any ttysleep()'s to return with ERESTART
2825  * and flush the tty.  The related fp's should already have been
2826  * replaced so the tty will close when the last references on the
2827  * original fp's go away.
2828  */
2829 int
2830 ttyrevoke(struct dev_revoke_args *ap)
2831 {
2832         struct tty *tp;
2833
2834         lwkt_gettoken(&tty_token);
2835         tp = ap->a_head.a_dev->si_tty;
2836         tp->t_gen++;
2837         ttyflush(tp, FREAD | FWRITE);
2838         wakeup(TSA_CARR_ON(tp));
2839         ttwakeup(tp);
2840         ttwwakeup(tp);
2841         lwkt_reltoken(&tty_token);
2842         return (0);
2843 }
2844
2845 /*
2846  * Allocate a tty struct.  Clists in the struct will be allocated by
2847  * ttyopen().
2848  */
2849 struct tty *
2850 ttymalloc(struct tty *tp)
2851 {
2852
2853         if (tp) {
2854                 return(tp);
2855         }
2856         tp = kmalloc(sizeof *tp, M_TTYS, M_WAITOK|M_ZERO);
2857         ttyregister(tp);
2858         return (tp);
2859 }
2860
2861 void
2862 ttyunregister(struct tty *tp)
2863 {
2864         lwkt_gettoken(&tty_token);
2865         KKASSERT(ISSET(tp->t_state, TS_REGISTERED));
2866         CLR(tp->t_state, TS_REGISTERED);
2867         TAILQ_REMOVE(&tty_list, tp, t_list);
2868         lwkt_reltoken(&tty_token);
2869 }
2870
2871 void
2872 ttyregister(struct tty *tp)
2873 {
2874         lwkt_gettoken(&tty_token);
2875         KKASSERT(!ISSET(tp->t_state, TS_REGISTERED));
2876         SET(tp->t_state, TS_REGISTERED);
2877         TAILQ_INSERT_HEAD(&tty_list, tp, t_list);
2878         lwkt_reltoken(&tty_token);
2879 }
2880
2881 static int
2882 sysctl_kern_ttys(SYSCTL_HANDLER_ARGS)
2883 {
2884         int error;
2885         struct tty *tp;
2886         struct tty t;
2887         struct tty marker;
2888
2889         bzero(&marker, sizeof(marker));
2890         marker.t_state = TS_MARKER;
2891         error = 0;
2892
2893         lwkt_gettoken(&tty_token);
2894
2895         TAILQ_INSERT_HEAD(&tty_list, &marker, t_list);
2896         while ((tp = TAILQ_NEXT(&marker, t_list)) != NULL) {
2897                 TAILQ_REMOVE(&tty_list, &marker, t_list);
2898                 TAILQ_INSERT_AFTER(&tty_list, tp, &marker, t_list);
2899                 if (tp->t_state & TS_MARKER)
2900                         continue;
2901                 t = *tp;
2902                 if (t.t_dev)
2903                         t.t_dev = (cdev_t)(uintptr_t)dev2udev(t.t_dev);
2904                 error = SYSCTL_OUT(req, (caddr_t)&t, sizeof(t));
2905                 if (error)
2906                         break;
2907         }
2908         TAILQ_REMOVE(&tty_list, &marker, t_list);
2909         lwkt_reltoken(&tty_token);
2910         return (error);
2911 }
2912
2913 SYSCTL_PROC(_kern, OID_AUTO, ttys, CTLTYPE_OPAQUE|CTLFLAG_RD,
2914         0, 0, sysctl_kern_ttys, "S,tty", "All struct ttys");
2915
2916 void
2917 nottystop(struct tty *tp, int rw)
2918 {
2919         return;
2920 }
2921
2922 int
2923 ttyread(struct dev_read_args *ap)
2924 {
2925         struct tty *tp;
2926         int ret;
2927
2928         tp = ap->a_head.a_dev->si_tty;
2929         if (tp == NULL)
2930                 return (ENODEV);
2931         lwkt_gettoken(&tty_token);
2932         ret = ((*linesw[tp->t_line].l_read)(tp, ap->a_uio, ap->a_ioflag));
2933         lwkt_reltoken(&tty_token);
2934
2935         return ret;
2936 }
2937
2938 int
2939 ttywrite(struct dev_write_args *ap)
2940 {
2941         struct tty *tp;
2942         int ret;
2943
2944         tp = ap->a_head.a_dev->si_tty;
2945         if (tp == NULL)
2946                 return (ENODEV);
2947         lwkt_gettoken(&tty_token);
2948         ret = ((*linesw[tp->t_line].l_write)(tp, ap->a_uio, ap->a_ioflag));
2949         lwkt_reltoken(&tty_token);
2950
2951         return ret;
2952 }