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