]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/kern/tty.c
Integrate the new MPSAFE TTY layer to the FreeBSD operating system.
[FreeBSD/FreeBSD.git] / sys / kern / tty.c
1 /*-
2  * Copyright (c) 2008 Ed Schouten <ed@FreeBSD.org>
3  * All rights reserved.
4  *
5  * Portions of this software were developed under sponsorship from Snow
6  * B.V., the Netherlands.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32
33 #include "opt_compat.h"
34
35 #include <sys/param.h>
36 #include <sys/conf.h>
37 #include <sys/cons.h>
38 #include <sys/fcntl.h>
39 #include <sys/filio.h>
40 #ifdef COMPAT_43TTY
41 #include <sys/ioctl_compat.h>
42 #endif /* COMPAT_43TTY */
43 #include <sys/kernel.h>
44 #include <sys/limits.h>
45 #include <sys/malloc.h>
46 #include <sys/mount.h>
47 #include <sys/namei.h>
48 #include <sys/poll.h>
49 #include <sys/priv.h>
50 #include <sys/proc.h>
51 #include <sys/serial.h>
52 #include <sys/signal.h>
53 #include <sys/stat.h>
54 #include <sys/sx.h>
55 #include <sys/sysctl.h>
56 #include <sys/systm.h>
57 #include <sys/tty.h>
58 #include <sys/ttycom.h>
59 #define TTYDEFCHARS
60 #include <sys/ttydefaults.h>
61 #undef TTYDEFCHARS
62 #include <sys/ucred.h>
63 #include <sys/vnode.h>
64
65 #include <machine/stdarg.h>
66
67 static MALLOC_DEFINE(M_TTY, "tty", "tty device");
68
69 static void tty_rel_free(struct tty *tp);
70
71 static TAILQ_HEAD(, tty) tty_list = TAILQ_HEAD_INITIALIZER(tty_list);
72 static struct sx tty_list_sx;
73 SX_SYSINIT(tty_list, &tty_list_sx, "tty list");
74 static unsigned int tty_list_count = 0;
75
76 /*
77  * Flags that are supported and stored by this implementation.
78  */
79 #define TTYSUP_IFLAG    (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK|ISTRIP|\
80                         INLCR|IGNCR|ICRNL|IXON|IXOFF|IXANY|IMAXBEL)
81 #define TTYSUP_OFLAG    (OPOST|ONLCR|TAB3|ONOEOT|OCRNL|ONOCR|ONLRET)
82 #define TTYSUP_LFLAG    (ECHOKE|ECHOE|ECHOK|ECHO|ECHONL|ECHOPRT|\
83                         ECHOCTL|ISIG|ICANON|ALTWERASE|IEXTEN|TOSTOP|\
84                         FLUSHO|NOKERNINFO|NOFLSH)
85 #define TTYSUP_CFLAG    (CIGNORE|CSIZE|CSTOPB|CREAD|PARENB|PARODD|\
86                         HUPCL|CLOCAL|CCTS_OFLOW|CRTS_IFLOW|CDTR_IFLOW|\
87                         CDSR_OFLOW|CCAR_OFLOW)
88
89 #define TTY_CALLOUT(tp,d) ((tp)->t_dev != (d))
90
91 /*
92  * Set TTY buffer sizes.
93  */
94
95 static void
96 tty_watermarks(struct tty *tp)
97 {
98         speed_t sp;
99
100         /* Provide an input buffer for 0.2 seconds of data. */
101         sp = MAX(tp->t_termios.c_ispeed, 0);
102         ttyinq_setsize(&tp->t_inq, tp, sp / 5);
103
104         /* Set low watermark at 10% (when 90% is available). */
105         tp->t_inlow = (ttyinq_getsize(&tp->t_inq) * 9) / 10;
106
107         /* Provide an ouput buffer for 0.2 seconds of data. */
108         sp = MAX(tp->t_termios.c_ospeed, 0);
109         ttyoutq_setsize(&tp->t_outq, tp, sp / 5);
110
111         /* Set low watermark at 10% (when 90% is available). */
112         tp->t_outlow = (ttyoutq_getsize(&tp->t_outq) * 9) / 10;
113 }
114
115 static void
116 tty_freebuffers(struct tty *tp)
117 {
118
119         /* Destroy input buffers. */
120         ttyinq_flush(&tp->t_inq);
121         ttyinq_setsize(&tp->t_inq, NULL, 0);
122         MPASS(ttyinq_getsize(&tp->t_inq) == 0);
123         tp->t_inlow = 0;
124
125         /* Destroy output buffers. */
126         ttyoutq_flush(&tp->t_outq);
127         ttyoutq_setsize(&tp->t_outq, NULL, 0);
128         MPASS(ttyoutq_getsize(&tp->t_outq) == 0);
129         tp->t_outlow = 0;
130 }
131
132 static int
133 tty_drain(struct tty *tp)
134 {
135         int error;
136
137         while (ttyoutq_bytesused(&tp->t_outq) > 0) {
138                 ttydevsw_outwakeup(tp);
139                 /* Could be handled synchronously. */
140                 if (ttyoutq_bytesused(&tp->t_outq) == 0)
141                         return (0);
142
143                 /* Wait for data to be drained. */
144                 error = tty_wait(tp, &tp->t_outwait);
145                 if (error)
146                         return (error);
147         }
148
149         return (0);
150 }
151
152 /*
153  * Because the revoke() call already calls d_close() without making sure
154  * all threads are purged from the TTY, we can only destroy the buffers
155  * and such when the last thread leaves the TTY. ttydev_enter() and
156  * ttydev_leave() are called from within the cdev functions, to make
157  * sure we can garbage collect the TTY.
158  */
159
160 static __inline int
161 ttydev_enter(struct tty *tp)
162 {
163         tty_lock(tp);
164
165         if (tty_gone(tp) || !tty_opened(tp)) {
166                 /* Device is already gone. */
167                 tty_unlock(tp);
168                 return (ENXIO);
169         }
170
171         return (0);
172 }
173
174 static void
175 ttydev_leave(struct tty *tp)
176 {
177         tty_lock_assert(tp, MA_OWNED);
178
179         if (tty_opened(tp) || tp->t_flags & TF_OPENCLOSE) {
180                 /* Device is still opened somewhere. */
181                 tty_unlock(tp);
182                 return;
183         }
184
185         tp->t_flags |= TF_OPENCLOSE;
186
187         /* Stop asynchronous I/O. */
188         funsetown(&tp->t_sigio);
189
190         /* Remove console TTY. */
191         if (constty == tp)
192                 constty_clear();
193
194         /* Drain any output. */
195         MPASS((tp->t_flags & TF_STOPPED) == 0);
196         if (!tty_gone(tp))
197                 tty_drain(tp);
198
199         ttydisc_close(tp);
200
201         /* Destroy associated buffers already. */
202         tty_freebuffers(tp);
203
204         knlist_clear(&tp->t_inpoll.si_note, 1);
205         knlist_clear(&tp->t_outpoll.si_note, 1);
206
207         if (!tty_gone(tp))
208                 ttydevsw_close(tp);
209
210         tp->t_flags &= ~TF_OPENCLOSE;
211         tty_rel_free(tp);
212 }
213
214 /*
215  * Operations that are exposed through the character device in /dev.
216  */
217 static int
218 ttydev_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
219 {
220         struct tty *tp = dev->si_drv1;
221         int error;
222
223         /* Disallow access when the TTY belongs to a different prison. */
224         if (dev->si_cred != NULL &&
225             dev->si_cred->cr_prison != td->td_ucred->cr_prison &&
226             priv_check(td, PRIV_TTY_PRISON)) {
227                 return (EPERM);
228         }
229
230         tty_lock(tp);
231         if (tty_gone(tp)) {
232                 /* Device is already gone. */
233                 tty_unlock(tp);
234                 return (ENXIO);
235         }
236         /*
237          * Prevent the TTY from being opened when being torn down or
238          * built up by unrelated processes.
239          */
240         if (tp->t_flags & TF_OPENCLOSE) {
241                 tty_unlock(tp);
242                 return (EBUSY);
243         }
244         tp->t_flags |= TF_OPENCLOSE;
245
246         /*
247          * Make sure the "tty" and "cua" device cannot be opened at the
248          * same time.
249          */
250         if (TTY_CALLOUT(tp, dev)) {
251                 if (tp->t_flags & TF_OPENED_IN) {
252                         error = EBUSY;
253                         goto done;
254                 }
255         } else {
256                 if (tp->t_flags & TF_OPENED_OUT) {
257                         error = EBUSY;
258                         goto done;
259                 }
260         }
261
262         if (tp->t_flags & TF_EXCLUDE && priv_check(td, PRIV_TTY_EXCLUSIVE)) {
263                 error = EBUSY;
264                 goto done;
265         }
266
267         if (!tty_opened(tp)) {
268                 /* Set proper termios flags. */
269                 if (TTY_CALLOUT(tp, dev)) {
270                         tp->t_termios = tp->t_termios_init_out;
271                 } else {
272                         tp->t_termios = tp->t_termios_init_in;
273                 }
274                 ttydevsw_param(tp, &tp->t_termios);
275
276                 ttydevsw_modem(tp, SER_DTR|SER_RTS, 0);
277
278                 error = ttydevsw_open(tp);
279                 if (error != 0)
280                         goto done;
281
282                 ttydisc_open(tp);
283                 tty_watermarks(tp);
284         }
285
286         /* Wait for Carrier Detect. */
287         if (!TTY_CALLOUT(tp, dev) && (oflags & O_NONBLOCK) == 0 &&
288             (tp->t_termios.c_cflag & CLOCAL) == 0) {
289                 while ((ttydevsw_modem(tp, 0, 0) & SER_DCD) == 0) {
290                         error = tty_wait(tp, &tp->t_dcdwait);
291                         if (error != 0)
292                                 goto done;
293                 }
294         }
295
296         if (TTY_CALLOUT(tp, dev)) {
297                 tp->t_flags |= TF_OPENED_OUT;
298         } else {
299                 tp->t_flags |= TF_OPENED_IN;
300         }
301
302 done:   tp->t_flags &= ~TF_OPENCLOSE;
303         ttydev_leave(tp);
304         return (error);
305 }
306
307 static int
308 ttydev_close(struct cdev *dev, int fflag, int devtype, struct thread *td)
309 {
310         struct tty *tp = dev->si_drv1;
311
312         tty_lock(tp);
313
314         /*
315          * This can only be called once. The callin and the callout
316          * devices cannot be opened at the same time.
317          */
318         MPASS((tp->t_flags & TF_OPENED) != TF_OPENED);
319         tp->t_flags &= ~(TF_OPENED|TF_EXCLUDE|TF_STOPPED);
320
321         /* Properly wake up threads that are stuck - revoke(). */
322         tp->t_revokecnt++;
323         tty_wakeup(tp, FREAD|FWRITE);
324         cv_broadcast(&tp->t_bgwait);
325
326         ttydev_leave(tp);
327
328         return (0);
329 }
330
331 static __inline int
332 tty_is_ctty(struct tty *tp, struct proc *p)
333 {
334         tty_lock_assert(tp, MA_OWNED);
335
336         return (p->p_session == tp->t_session && p->p_flag & P_CONTROLT);
337 }
338
339 static int
340 tty_wait_background(struct tty *tp, struct thread *td, int sig)
341 {
342         struct proc *p = td->td_proc;
343         struct pgrp *pg;
344         int error;
345
346         MPASS(sig == SIGTTIN || sig == SIGTTOU);
347         tty_lock_assert(tp, MA_OWNED);
348
349         for (;;) {
350                 PROC_LOCK(p);
351                 /*
352                  * The process should only sleep, when:
353                  * - This terminal is the controling terminal
354                  * - Its process group is not the foreground process
355                  *   group
356                  * - The parent process isn't waiting for the child to
357                  *   exit
358                  * - the signal to send to the process isn't masked
359                  */
360                 if (!tty_is_ctty(tp, p) ||
361                     p->p_pgrp == tp->t_pgrp || p->p_flag & P_PPWAIT ||
362                     SIGISMEMBER(p->p_sigacts->ps_sigignore, sig) ||
363                     SIGISMEMBER(td->td_sigmask, sig)) {
364                         /* Allow the action to happen. */
365                         PROC_UNLOCK(p);
366                         return (0);
367                 }
368
369                 /*
370                  * Send the signal and sleep until we're the new
371                  * foreground process group.
372                  */
373                 pg = p->p_pgrp;
374                 PROC_UNLOCK(p);
375                 if (pg->pg_jobc == 0)
376                         return (EIO);
377                 PGRP_LOCK(pg);
378                 pgsignal(pg, sig, 1);
379                 PGRP_UNLOCK(pg);
380
381                 error = tty_wait(tp, &tp->t_bgwait);
382                 if (error)
383                         return (error);
384         }
385 }
386
387 static int
388 ttydev_read(struct cdev *dev, struct uio *uio, int ioflag)
389 {
390         struct tty *tp = dev->si_drv1;
391         int error;
392
393         error = ttydev_enter(tp);
394         if (error)
395                 return (0);
396
397         error = tty_wait_background(tp, curthread, SIGTTIN);
398         if (error)
399                 goto done;
400
401         error = ttydisc_read(tp, uio, ioflag);
402 done:   ttydev_leave(tp);
403
404         /*
405          * The read() and write() calls should not throw an error when
406          * the device is ripped offline.
407          */
408         if (error == ENXIO)
409                 return (0);
410
411         return (error);
412 }
413
414 static int
415 ttydev_write(struct cdev *dev, struct uio *uio, int ioflag)
416 {
417         struct tty *tp = dev->si_drv1;
418         int error;
419
420         error = ttydev_enter(tp);
421         if (error)
422                 return (0);
423
424         if (tp->t_termios.c_lflag & TOSTOP) {
425                 error = tty_wait_background(tp, curthread, SIGTTOU);
426                 if (error)
427                         goto done;
428         }
429
430         error = ttydisc_write(tp, uio, ioflag);
431 done:   ttydev_leave(tp);
432
433         /*
434          * The read() and write() calls should not throw an error when
435          * the device is ripped offline.
436          */
437         if (error == ENXIO)
438                 return (0);
439
440         return (error);
441 }
442
443 static int
444 ttydev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
445     struct thread *td)
446 {
447         struct tty *tp = dev->si_drv1;
448         int error;
449
450         error = ttydev_enter(tp);
451         if (error)
452                 return (error);
453
454         switch (cmd) {
455         case TIOCCBRK:
456         case TIOCCONS:
457         case TIOCDRAIN:
458         case TIOCEXCL:
459         case TIOCFLUSH:
460         case TIOCNXCL:
461         case TIOCSBRK:
462         case TIOCSCTTY:
463         case TIOCSETA:
464         case TIOCSETAF:
465         case TIOCSETAW:
466         case TIOCSPGRP:
467         case TIOCSTART:
468         case TIOCSTAT:
469         case TIOCSTOP:
470         case TIOCSWINSZ:
471 #if 0
472         case TIOCSDRAINWAIT:
473         case TIOCSETD:
474         case TIOCSTI:
475 #endif
476 #ifdef COMPAT_43TTY
477         case  TIOCLBIC:
478         case  TIOCLBIS:
479         case  TIOCLSET:
480         case  TIOCSETC:
481         case OTIOCSETD:
482         case  TIOCSETN:
483         case  TIOCSETP:
484         case  TIOCSLTC:
485 #endif /* COMPAT_43TTY */
486                 /*
487                  * If the ioctl() causes the TTY to be modified, let it
488                  * wait in the background.
489                  */
490                 error = tty_wait_background(tp, curthread, SIGTTOU);
491                 if (error)
492                         goto done;
493         }
494
495         error = tty_ioctl(tp, cmd, data, td);
496 done:   ttydev_leave(tp);
497
498         return (error);
499 }
500
501 static int
502 ttydev_poll(struct cdev *dev, int events, struct thread *td)
503 {
504         struct tty *tp = dev->si_drv1;
505         int error, revents = 0;
506
507         error = ttydev_enter(tp);
508         if (error) {
509                 /* Don't return the error here, but the event mask. */
510                 return (events &
511                     (POLLHUP|POLLIN|POLLRDNORM|POLLOUT|POLLWRNORM));
512         }
513
514         if (events & (POLLIN|POLLRDNORM)) {
515                 /* See if we can read something. */
516                 if (ttydisc_read_poll(tp) > 0)
517                         revents |= events & (POLLIN|POLLRDNORM);
518         }
519         if (events & (POLLOUT|POLLWRNORM)) {
520                 /* See if we can write something. */
521                 if (ttydisc_write_poll(tp) > 0)
522                         revents |= events & (POLLOUT|POLLWRNORM);
523         }
524         if (tp->t_flags & TF_ZOMBIE)
525                 /* Hangup flag on zombie state. */
526                 revents |= events & POLLHUP;
527
528         if (revents == 0) {
529                 if (events & (POLLIN|POLLRDNORM))
530                         selrecord(td, &tp->t_inpoll);
531                 if (events & (POLLOUT|POLLWRNORM))
532                         selrecord(td, &tp->t_outpoll);
533         }
534
535         ttydev_leave(tp);
536
537         return (revents);
538 }
539
540 static int
541 ttydev_mmap(struct cdev *dev, vm_offset_t offset, vm_paddr_t *paddr, int nprot)
542 {
543         struct tty *tp = dev->si_drv1;
544         int error;
545
546         /* Handle mmap() through the driver. */
547
548         error = ttydev_enter(tp);
549         if (error)
550                 return (-1);
551         error = ttydevsw_mmap(tp, offset, paddr, nprot);
552         ttydev_leave(tp);
553
554         return (error);
555 }
556
557 /*
558  * kqueue support.
559  */
560
561 static void
562 tty_kqops_read_detach(struct knote *kn)
563 {
564         struct tty *tp = kn->kn_hook;
565
566         knlist_remove(&tp->t_inpoll.si_note, kn, 0);
567 }
568
569 static int
570 tty_kqops_read_event(struct knote *kn, long hint)
571 {
572         struct tty *tp = kn->kn_hook;
573
574         tty_lock_assert(tp, MA_OWNED);
575
576         if (tty_gone(tp) || tp->t_flags & TF_ZOMBIE) {
577                 kn->kn_flags |= EV_EOF;
578                 return (1);
579         } else {
580                 kn->kn_data = ttydisc_read_poll(tp);
581                 return (kn->kn_data > 0);
582         }
583 }
584
585 static void
586 tty_kqops_write_detach(struct knote *kn)
587 {
588         struct tty *tp = kn->kn_hook;
589
590         knlist_remove(&tp->t_outpoll.si_note, kn, 0);
591 }
592
593 static int
594 tty_kqops_write_event(struct knote *kn, long hint)
595 {
596         struct tty *tp = kn->kn_hook;
597
598         tty_lock_assert(tp, MA_OWNED);
599
600         if (tty_gone(tp)) {
601                 kn->kn_flags |= EV_EOF;
602                 return (1);
603         } else {
604                 kn->kn_data = ttydisc_write_poll(tp);
605                 return (kn->kn_data > 0);
606         }
607 }
608
609 static struct filterops tty_kqops_read =
610     { 1, NULL, tty_kqops_read_detach, tty_kqops_read_event };
611 static struct filterops tty_kqops_write =
612     { 1, NULL, tty_kqops_write_detach, tty_kqops_write_event };
613
614 static int
615 ttydev_kqfilter(struct cdev *dev, struct knote *kn)
616 {
617         struct tty *tp = dev->si_drv1;
618         int error;
619
620         error = ttydev_enter(tp);
621         if (error)
622                 return (error);
623
624         switch (kn->kn_filter) {
625         case EVFILT_READ:
626                 kn->kn_hook = tp;
627                 kn->kn_fop = &tty_kqops_read;
628                 knlist_add(&tp->t_inpoll.si_note, kn, 1);
629                 break;
630         case EVFILT_WRITE:
631                 kn->kn_hook = tp;
632                 kn->kn_fop = &tty_kqops_write;
633                 knlist_add(&tp->t_outpoll.si_note, kn, 1);
634                 break;
635         default:
636                 error = EINVAL;
637                 break;
638         }
639
640         ttydev_leave(tp);
641         return (error);
642 }
643
644 static struct cdevsw ttydev_cdevsw = {
645         .d_version      = D_VERSION,
646         .d_open         = ttydev_open,
647         .d_close        = ttydev_close,
648         .d_read         = ttydev_read,
649         .d_write        = ttydev_write,
650         .d_ioctl        = ttydev_ioctl,
651         .d_kqfilter     = ttydev_kqfilter,
652         .d_poll         = ttydev_poll,
653         .d_mmap         = ttydev_mmap,
654         .d_name         = "ttydev",
655         .d_flags        = D_TTY,
656 };
657
658 /*
659  * Init/lock-state devices
660  */
661
662 static int
663 ttyil_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
664 {
665         struct tty *tp = dev->si_drv1;
666         int error = 0;
667
668         tty_lock(tp);
669         if (tty_gone(tp))
670                 error = ENODEV;
671         tty_unlock(tp);
672
673         return (error);
674 }
675
676 static int
677 ttyil_close(struct cdev *dev, int flag, int mode, struct thread *td)
678 {
679         return (0);
680 }
681
682 static int
683 ttyil_rdwr(struct cdev *dev, struct uio *uio, int ioflag)
684 {
685         return (ENODEV);
686 }
687
688 static int
689 ttyil_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag,
690     struct thread *td)
691 {
692         struct tty *tp = dev->si_drv1;
693         int error = 0;
694
695         tty_lock(tp);
696         if (tty_gone(tp)) {
697                 error = ENODEV;
698                 goto done;
699         }
700
701         switch (cmd) {
702         case TIOCGETA:
703                 /* Obtain terminal flags through tcgetattr(). */
704                 bcopy(dev->si_drv2, data, sizeof(struct termios));
705                 break;
706         case TIOCSETA:
707                 /* Set terminal flags through tcsetattr(). */
708                 error = priv_check(td, PRIV_TTY_SETA);
709                 if (error)
710                         break;
711                 bcopy(data, dev->si_drv2, sizeof(struct termios));
712                 return (0);
713                 break;
714         case TIOCGETD:
715                 *(int *)data = TTYDISC;
716                 break;
717         case TIOCGWINSZ:
718                 bzero(data, sizeof(struct winsize));
719                 break;
720         default:
721                 error = ENOTTY;
722         }
723
724 done:   tty_unlock(tp);
725         return (error);
726 }
727
728 static struct cdevsw ttyil_cdevsw = {
729         .d_version      = D_VERSION,
730         .d_open         = ttyil_open,
731         .d_close        = ttyil_close,
732         .d_read         = ttyil_rdwr,
733         .d_write        = ttyil_rdwr,
734         .d_ioctl        = ttyil_ioctl,
735         .d_name         = "ttyil",
736         .d_flags        = D_TTY,
737 };
738
739 static void
740 tty_init_termios(struct tty *tp)
741 {
742         struct termios *t = &tp->t_termios_init_in;
743
744         t->c_cflag = TTYDEF_CFLAG;
745         t->c_iflag = TTYDEF_IFLAG;
746         t->c_lflag = TTYDEF_LFLAG;
747         t->c_oflag = TTYDEF_OFLAG;
748         t->c_ispeed = TTYDEF_SPEED;
749         t->c_ospeed = TTYDEF_SPEED;
750         bcopy(ttydefchars, &t->c_cc, sizeof ttydefchars);
751
752         tp->t_termios_init_out = *t;
753 }
754
755 void
756 tty_init_console(struct tty *tp, speed_t s)
757 {
758         struct termios *ti = &tp->t_termios_init_in;
759         struct termios *to = &tp->t_termios_init_out;
760
761         if (s != 0) {
762                 ti->c_ispeed = ti->c_ospeed = s;
763                 to->c_ispeed = to->c_ospeed = s;
764         }
765
766         ti->c_cflag |= CLOCAL;
767         to->c_cflag |= CLOCAL;
768 }
769
770 /*
771  * Standard device routine implementations, mostly meant for
772  * pseudo-terminal device drivers. When a driver creates a new terminal
773  * device class, missing routines are patched.
774  */
775
776 static int
777 ttydevsw_defopen(struct tty *tp)
778 {
779
780         return (0);
781 }
782
783 static void
784 ttydevsw_defclose(struct tty *tp)
785 {
786 }
787
788 static void
789 ttydevsw_defoutwakeup(struct tty *tp)
790 {
791
792         panic("Terminal device has output, while not implemented");
793 }
794
795 static void
796 ttydevsw_definwakeup(struct tty *tp)
797 {
798 }
799
800 static int
801 ttydevsw_defioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
802 {
803
804         return (ENOIOCTL);
805 }
806
807 static int
808 ttydevsw_defparam(struct tty *tp, struct termios *t)
809 {
810
811         /* Use a fake baud rate, we're not a real device. */
812         t->c_ispeed = t->c_ospeed = TTYDEF_SPEED_PSEUDO;
813
814         return (0);
815 }
816
817 static int
818 ttydevsw_defmodem(struct tty *tp, int sigon, int sigoff)
819 {
820
821         /* Simulate a carrier to make the TTY layer happy. */
822         return (SER_DCD);
823 }
824
825 static int
826 ttydevsw_defmmap(struct tty *tp, vm_offset_t offset, vm_paddr_t *paddr,
827     int nprot)
828 {
829
830         return (-1);
831 }
832
833 static void
834 ttydevsw_deffree(void *softc)
835 {
836
837         panic("Terminal device freed without a free-handler");
838 }
839
840 /*
841  * TTY allocation and deallocation. TTY devices can be deallocated when
842  * the driver doesn't use it anymore, when the TTY isn't a session's
843  * controlling TTY and when the device node isn't opened through devfs.
844  */
845
846 struct tty *
847 tty_alloc(struct ttydevsw *tsw, void *sc, struct mtx *mutex)
848 {
849         struct tty *tp;
850
851         /* Make sure the driver defines all routines. */
852 #define PATCH_FUNC(x) do {                              \
853         if (tsw->tsw_ ## x == NULL)                     \
854                 tsw->tsw_ ## x = ttydevsw_def ## x;     \
855 } while (0)
856         PATCH_FUNC(open);
857         PATCH_FUNC(close);
858         PATCH_FUNC(outwakeup);
859         PATCH_FUNC(inwakeup);
860         PATCH_FUNC(ioctl);
861         PATCH_FUNC(param);
862         PATCH_FUNC(modem);
863         PATCH_FUNC(mmap);
864         PATCH_FUNC(free);
865 #undef PATCH_FUNC
866
867         tp = malloc(sizeof(struct tty), M_TTY, M_WAITOK|M_ZERO);
868         tp->t_devsw = tsw;
869         tp->t_softc = sc;
870         tp->t_flags = tsw->tsw_flags;
871
872         tty_init_termios(tp);
873
874         cv_init(&tp->t_inwait, "tty input");
875         cv_init(&tp->t_outwait, "tty output");
876         cv_init(&tp->t_bgwait, "tty background");
877         cv_init(&tp->t_dcdwait, "tty dcd");
878
879         TAILQ_INIT(&tp->t_inq.ti_list);
880         STAILQ_INIT(&tp->t_outq.to_list);
881
882         /* Allow drivers to use a custom mutex to lock the TTY. */
883         if (mutex != NULL) {
884                 tp->t_mtx = mutex;
885         } else {
886                 tp->t_mtx = &tp->t_mtxobj;
887                 mtx_init(&tp->t_mtxobj, "tty lock", NULL, MTX_DEF);
888         }
889
890         knlist_init(&tp->t_inpoll.si_note, tp->t_mtx, NULL, NULL, NULL);
891         knlist_init(&tp->t_outpoll.si_note, tp->t_mtx, NULL, NULL, NULL);
892
893         sx_xlock(&tty_list_sx);
894         TAILQ_INSERT_TAIL(&tty_list, tp, t_list);
895         tty_list_count++;
896         sx_xunlock(&tty_list_sx);
897
898         return (tp);
899 }
900
901 static void
902 tty_dealloc(void *arg)
903 {
904         struct tty *tp = arg;
905
906         sx_xlock(&tty_list_sx);
907         TAILQ_REMOVE(&tty_list, tp, t_list);
908         tty_list_count--;
909         sx_xunlock(&tty_list_sx);
910
911         knlist_destroy(&tp->t_inpoll.si_note);
912         knlist_destroy(&tp->t_outpoll.si_note);
913
914         cv_destroy(&tp->t_inwait);
915         cv_destroy(&tp->t_outwait);
916         cv_destroy(&tp->t_bgwait);
917         cv_destroy(&tp->t_dcdwait);
918
919         if (tp->t_mtx == &tp->t_mtxobj)
920                 mtx_destroy(&tp->t_mtxobj);
921         ttydevsw_free(tp);
922         free(tp, M_TTY);
923 }
924
925 static void
926 tty_rel_free(struct tty *tp)
927 {
928         struct cdev *dev;
929
930         tty_lock_assert(tp, MA_OWNED);
931
932         if (tp->t_sessioncnt != 0 ||
933             (tp->t_flags & (TF_GONE|TF_OPENED)) != TF_GONE) {
934                 /* TTY is still in use. */
935                 tty_unlock(tp);
936                 return;
937         }
938
939         tty_freebuffers(tp);
940
941         /* TTY can be deallocated. */
942         dev = tp->t_dev;
943         tp->t_dev = NULL;
944         tty_unlock(tp);
945
946         destroy_dev_sched_cb(dev, tty_dealloc, tp);
947 }
948
949 void
950 tty_rel_pgrp(struct tty *tp, struct pgrp *pg)
951 {
952         tty_lock_assert(tp, MA_OWNED);
953
954         if (tp->t_pgrp == pg)
955                 tp->t_pgrp = NULL;
956 }
957
958 void
959 tty_rel_sess(struct tty *tp, struct session *sess)
960 {
961         MPASS(tp->t_sessioncnt > 0);
962
963         /* Current session has left. */
964         if (tp->t_session == sess) {
965                 tp->t_session = NULL;
966                 MPASS(tp->t_pgrp == NULL);
967         }
968         tp->t_sessioncnt--;
969         tty_rel_free(tp);
970 }
971
972 void
973 tty_rel_gone(struct tty *tp)
974 {
975         MPASS(!tty_gone(tp));
976
977         /* Simulate carrier removal. */
978         ttydisc_modem(tp, 0);
979
980         /* Wake up misc. blocked threads. */
981         cv_broadcast(&tp->t_bgwait);
982         cv_broadcast(&tp->t_dcdwait);
983
984         tp->t_flags |= TF_GONE;
985         tty_rel_free(tp);
986 }
987
988 /*
989  * Exposing information about current TTY's through sysctl
990  */
991
992 static void
993 tty_to_xtty(struct tty *tp, struct xtty *xt)
994 {
995         tty_lock_assert(tp, MA_OWNED);
996
997         xt->xt_size = sizeof(struct xtty);
998         xt->xt_insize = ttyinq_getsize(&tp->t_inq);
999         xt->xt_incc = ttyinq_bytescanonicalized(&tp->t_inq);
1000         xt->xt_inlc = ttyinq_bytesline(&tp->t_inq);
1001         xt->xt_inlow = tp->t_inlow;
1002         xt->xt_outsize = ttyoutq_getsize(&tp->t_outq);
1003         xt->xt_outcc = ttyoutq_bytesused(&tp->t_outq);
1004         xt->xt_outlow = tp->t_outlow;
1005         xt->xt_column = tp->t_column;
1006         xt->xt_pgid = tp->t_pgrp ? tp->t_pgrp->pg_id : 0;
1007         xt->xt_sid = tp->t_session ? tp->t_session->s_sid : 0;
1008         xt->xt_flags = tp->t_flags;
1009         xt->xt_dev = tp->t_dev ? dev2udev(tp->t_dev) : NODEV;
1010 }
1011
1012 static int
1013 sysctl_kern_ttys(SYSCTL_HANDLER_ARGS)
1014 {
1015         unsigned long lsize;
1016         struct xtty *xtlist, *xt;
1017         struct tty *tp;
1018         int error;
1019
1020         sx_slock(&tty_list_sx);
1021         lsize = tty_list_count * sizeof(struct xtty);
1022         if (lsize == 0) {
1023                 sx_sunlock(&tty_list_sx);
1024                 return (0);
1025         }
1026
1027         xtlist = xt = malloc(lsize, M_TEMP, M_WAITOK);
1028
1029         TAILQ_FOREACH(tp, &tty_list, t_list) {
1030                 tty_lock(tp);
1031                 tty_to_xtty(tp, xt);
1032                 tty_unlock(tp);
1033                 xt++;
1034         }
1035         sx_sunlock(&tty_list_sx);
1036
1037         error = SYSCTL_OUT(req, xtlist, lsize);
1038         free(xtlist, M_TEMP);
1039         return (error);
1040 }
1041
1042 SYSCTL_PROC(_kern, OID_AUTO, ttys, CTLTYPE_OPAQUE|CTLFLAG_RD,
1043         0, 0, sysctl_kern_ttys, "S,xtty", "List of TTYs");
1044
1045 /*
1046  * Device node creation. Device has been set up, now we can expose it to
1047  * the user.
1048  */
1049
1050 void
1051 tty_makedev(struct tty *tp, struct ucred *cred, const char *fmt, ...)
1052 {
1053         va_list ap;
1054         struct cdev *dev;
1055         const char *prefix = "tty";
1056         char name[SPECNAMELEN - 3]; /* for "tty" and "cua". */
1057         uid_t uid;
1058         gid_t gid;
1059         mode_t mode;
1060
1061         /* Remove "tty" prefix from devices like PTY's. */
1062         if (tp->t_flags & TF_NOPREFIX)
1063                 prefix = "";
1064
1065         va_start(ap, fmt);
1066         vsnrprintf(name, sizeof name, 32, fmt, ap);
1067         va_end(ap);
1068
1069         if (cred == NULL) {
1070                 /* System device. */
1071                 uid = UID_ROOT;
1072                 gid = GID_WHEEL;
1073                 mode = S_IRUSR|S_IWUSR;
1074         } else {
1075                 /* User device. */
1076                 uid = cred->cr_ruid;
1077                 gid = GID_TTY;
1078                 mode = S_IRUSR|S_IWUSR|S_IWGRP;
1079         }
1080
1081         /* Master call-in device. */
1082         dev = make_dev_cred(&ttydev_cdevsw, 0, cred,
1083             uid, gid, mode, "%s%s", prefix, name);
1084         dev->si_drv1 = tp;
1085         tp->t_dev = dev;
1086
1087         /* Slave call-in devices. */
1088         if (tp->t_flags & TF_INITLOCK) {
1089                 dev = make_dev_cred(&ttyil_cdevsw, 0, cred,
1090                     uid, gid, mode, "%s%s.init", prefix, name);
1091                 dev_depends(tp->t_dev, dev);
1092                 dev->si_drv1 = tp;
1093                 dev->si_drv2 = &tp->t_termios_init_in;
1094
1095                 dev = make_dev_cred(&ttyil_cdevsw, 0, cred,
1096                     uid, gid, mode, "%s%s.lock", prefix, name);
1097                 dev_depends(tp->t_dev, dev);
1098                 dev->si_drv1 = tp;
1099                 dev->si_drv2 = &tp->t_termios_lock_in;
1100         }
1101
1102         /* Call-out devices. */
1103         if (tp->t_flags & TF_CALLOUT) {
1104                 dev = make_dev_cred(&ttydev_cdevsw, 0, cred,
1105                     UID_UUCP, GID_DIALER, 0660, "cua%s", name);
1106                 dev_depends(tp->t_dev, dev);
1107                 dev->si_drv1 = tp;
1108
1109                 /* Slave call-out devices. */
1110                 if (tp->t_flags & TF_INITLOCK) {
1111                         dev = make_dev_cred(&ttyil_cdevsw, 0, cred,
1112                             UID_UUCP, GID_DIALER, 0660, "cua%s.init", name);
1113                         dev_depends(tp->t_dev, dev);
1114                         dev->si_drv1 = tp;
1115                         dev->si_drv2 = &tp->t_termios_init_out;
1116
1117                         dev = make_dev_cred(&ttyil_cdevsw, 0, cred,
1118                             UID_UUCP, GID_DIALER, 0660, "cua%s.lock", name);
1119                         dev_depends(tp->t_dev, dev);
1120                         dev->si_drv1 = tp;
1121                         dev->si_drv2 = &tp->t_termios_lock_out;
1122                 }
1123         }
1124 }
1125
1126 /*
1127  * Signalling processes.
1128  */
1129
1130 void
1131 tty_signal_sessleader(struct tty *tp, int sig)
1132 {
1133         struct proc *p;
1134
1135         tty_lock_assert(tp, MA_OWNED);
1136         MPASS(sig >= 1 && sig < NSIG);
1137
1138         /* Make signals start output again. */
1139         tp->t_flags &= ~TF_STOPPED;
1140         
1141         if (tp->t_session != NULL && tp->t_session->s_leader != NULL) {
1142                 p = tp->t_session->s_leader;
1143                 PROC_LOCK(p);
1144                 psignal(p, sig);
1145                 PROC_UNLOCK(p);
1146         }
1147 }
1148
1149 void
1150 tty_signal_pgrp(struct tty *tp, int sig)
1151 {
1152         tty_lock_assert(tp, MA_OWNED);
1153         MPASS(sig >= 1 && sig < NSIG);
1154
1155         /* Make signals start output again. */
1156         tp->t_flags &= ~TF_STOPPED;
1157
1158         if (sig == SIGINFO && !(tp->t_termios.c_lflag & NOKERNINFO))
1159                 tty_info(tp);
1160         if (tp->t_pgrp != NULL) {
1161                 PGRP_LOCK(tp->t_pgrp);
1162                 pgsignal(tp->t_pgrp, sig, 1);
1163                 PGRP_UNLOCK(tp->t_pgrp);
1164         }
1165 }
1166
1167 void
1168 tty_wakeup(struct tty *tp, int flags)
1169 {
1170         if (tp->t_flags & TF_ASYNC && tp->t_sigio != NULL)
1171                 pgsigio(&tp->t_sigio, SIGIO, (tp->t_session != NULL));
1172
1173         if (flags & FWRITE) {
1174                 cv_broadcast(&tp->t_outwait);
1175                 selwakeup(&tp->t_outpoll);
1176                 KNOTE_LOCKED(&tp->t_outpoll.si_note, 0);
1177         }
1178         if (flags & FREAD) {
1179                 cv_broadcast(&tp->t_inwait);
1180                 selwakeup(&tp->t_inpoll);
1181                 KNOTE_LOCKED(&tp->t_inpoll.si_note, 0);
1182         }
1183 }
1184
1185 int
1186 tty_wait(struct tty *tp, struct cv *cv)
1187 {
1188         int error;
1189         int revokecnt = tp->t_revokecnt;
1190
1191 #if 0
1192         /* XXX: /dev/console also picks up Giant. */
1193         tty_lock_assert(tp, MA_OWNED|MA_NOTRECURSED);
1194 #endif
1195         tty_lock_assert(tp, MA_OWNED);
1196
1197         error = cv_wait_sig(cv, tp->t_mtx);
1198
1199         /* Restart the system call when we may have been revoked. */
1200         if (tp->t_revokecnt != revokecnt)
1201                 return (ERESTART);
1202         
1203         /* Bail out when the device slipped away. */
1204         if (tty_gone(tp))
1205                 return (ENXIO);
1206
1207         return (error);
1208 }
1209
1210 int
1211 tty_timedwait(struct tty *tp, struct cv *cv, int hz)
1212 {
1213         int error;
1214         int revokecnt = tp->t_revokecnt;
1215
1216 #if 0
1217         /* XXX: /dev/console also picks up Giant. */
1218         tty_lock_assert(tp, MA_OWNED|MA_NOTRECURSED);
1219 #endif
1220         tty_lock_assert(tp, MA_OWNED);
1221
1222         error = cv_timedwait_sig(cv, tp->t_mtx, hz);
1223
1224         /* Restart the system call when we may have been revoked. */
1225         if (tp->t_revokecnt != revokecnt)
1226                 return (ERESTART);
1227         
1228         /* Bail out when the device slipped away. */
1229         if (tty_gone(tp))
1230                 return (ENXIO);
1231
1232         return (error);
1233 }
1234
1235 void
1236 tty_flush(struct tty *tp, int flags)
1237 {
1238         if (flags & FWRITE) {
1239                 tp->t_flags &= ~TF_HIWAT_OUT;
1240                 ttyoutq_flush(&tp->t_outq);
1241                 tty_wakeup(tp, FWRITE);
1242         }
1243         if (flags & FREAD) {
1244                 tty_hiwat_in_unblock(tp);
1245                 ttyinq_flush(&tp->t_inq);
1246                 ttydevsw_inwakeup(tp);
1247         }
1248 }
1249
1250 static int
1251 tty_generic_ioctl(struct tty *tp, u_long cmd, void *data, struct thread *td)
1252 {
1253         int error;
1254
1255         switch (cmd) {
1256         /*
1257          * Modem commands.
1258          * The SER_* and TIOCM_* flags are the same, but one bit
1259          * shifted. I don't know why.
1260          */
1261         case TIOCSDTR:
1262                 ttydevsw_modem(tp, SER_DTR, 0);
1263                 return (0);
1264         case TIOCCDTR:
1265                 ttydevsw_modem(tp, 0, SER_DTR);
1266                 return (0);
1267         case TIOCMSET: {
1268                 int bits = *(int *)data;
1269                 ttydevsw_modem(tp,
1270                     (bits & (TIOCM_DTR | TIOCM_RTS)) >> 1,
1271                     ((~bits) & (TIOCM_DTR | TIOCM_RTS)) >> 1);
1272                 return (0);
1273         }
1274         case TIOCMBIS: {
1275                 int bits = *(int *)data;
1276                 ttydevsw_modem(tp, (bits & (TIOCM_DTR | TIOCM_RTS)) >> 1, 0);
1277                 return (0);
1278         }
1279         case TIOCMBIC: {
1280                 int bits = *(int *)data;
1281                 ttydevsw_modem(tp, 0, (bits & (TIOCM_DTR | TIOCM_RTS)) >> 1);
1282                 return (0);
1283         }
1284         case TIOCMGET:
1285                 *(int *)data = TIOCM_LE + (ttydevsw_modem(tp, 0, 0) << 1);
1286                 return (0);
1287
1288         case FIOASYNC:
1289                 if (*(int *)data)
1290                         tp->t_flags |= TF_ASYNC;
1291                 else
1292                         tp->t_flags &= ~TF_ASYNC;
1293                 return (0);
1294         case FIONBIO:
1295                 /* This device supports non-blocking operation. */
1296                 return (0);
1297         case FIONREAD:
1298                 *(int *)data = ttyinq_bytescanonicalized(&tp->t_inq);
1299                 return (0);
1300         case FIOSETOWN:
1301                 if (tp->t_session != NULL && !tty_is_ctty(tp, td->td_proc))
1302                         /* Not allowed to set ownership. */
1303                         return (ENOTTY);
1304
1305                 /* Temporarily unlock the TTY to set ownership. */
1306                 tty_unlock(tp);
1307                 error = fsetown(*(int *)data, &tp->t_sigio);
1308                 tty_lock(tp);
1309                 return (error);
1310         case FIOGETOWN:
1311                 if (tp->t_session != NULL && !tty_is_ctty(tp, td->td_proc))
1312                         /* Not allowed to set ownership. */
1313                         return (ENOTTY);
1314
1315                 /* Get ownership. */
1316                 *(int *)data = fgetown(&tp->t_sigio);
1317                 return (0);
1318         case TIOCGETA:
1319                 /* Obtain terminal flags through tcgetattr(). */
1320                 bcopy(&tp->t_termios, data, sizeof(struct termios));
1321                 return (0);
1322         case TIOCSETA:
1323         case TIOCSETAW:
1324         case TIOCSETAF: {
1325                 struct termios *t = data;
1326
1327                 /*
1328                  * Who makes up these funny rules? According to POSIX,
1329                  * input baud rate is set equal to the output baud rate
1330                  * when zero.
1331                  */
1332                 if (t->c_ispeed == 0)
1333                         t->c_ispeed = t->c_ospeed;
1334
1335                 /* Don't allow invalid flags to be set. */
1336                 if ((t->c_iflag & ~TTYSUP_IFLAG) != 0 ||
1337                     (t->c_oflag & ~TTYSUP_OFLAG) != 0 ||
1338                     (t->c_lflag & ~TTYSUP_LFLAG) != 0 ||
1339                     (t->c_cflag & ~TTYSUP_CFLAG) != 0)
1340                         return (EINVAL);
1341
1342                 /* Set terminal flags through tcsetattr(). */
1343                 if (cmd == TIOCSETAW || cmd == TIOCSETAF) {
1344                         error = tty_drain(tp);
1345                         if (error)
1346                                 return (error);
1347                         if (cmd == TIOCSETAF)
1348                                 tty_flush(tp, FREAD);
1349                 }
1350
1351                 /*
1352                  * Only call param() when the flags really change.
1353                  */
1354                 if ((t->c_cflag & CIGNORE) == 0 &&
1355                     (tp->t_termios.c_cflag != t->c_cflag ||
1356                     tp->t_termios.c_ispeed != t->c_ispeed ||
1357                     tp->t_termios.c_ospeed != t->c_ospeed)) {
1358                         error = ttydevsw_param(tp, t);
1359                         if (error)
1360                                 return (error);
1361
1362                         /* XXX: CLOCAL? */
1363                         
1364                         tp->t_termios.c_cflag = t->c_cflag;
1365                         tp->t_termios.c_ispeed = t->c_ispeed;
1366                         tp->t_termios.c_ospeed = t->c_ospeed;
1367
1368                         /* Baud rate has changed - update watermarks. */
1369                         tty_watermarks(tp);
1370                 }
1371
1372                 /* Copy new non-device driver parameters. */
1373                 tp->t_termios.c_iflag = t->c_iflag;
1374                 tp->t_termios.c_oflag = t->c_oflag;
1375                 tp->t_termios.c_lflag = t->c_lflag;
1376                 bcopy(t->c_cc, &tp->t_termios.c_cc, sizeof(t->c_cc));
1377
1378                 ttydisc_optimize(tp);
1379
1380                 if ((t->c_lflag & ICANON) == 0) {
1381                         /*
1382                          * When in non-canonical mode, wake up all
1383                          * readers. Canonicalize any partial input. VMIN
1384                          * and VTIME could also be adjusted.
1385                          */
1386                         ttyinq_canonicalize(&tp->t_inq);
1387                         tty_wakeup(tp, FREAD);
1388                 }
1389                 return (0);
1390         }
1391         case TIOCGETD:
1392                 /* For compatibility - we only support TTYDISC. */
1393                 *(int *)data = TTYDISC;
1394                 return (0);
1395         case TIOCGPGRP:
1396                 if (!tty_is_ctty(tp, td->td_proc))
1397                         return (ENOTTY);
1398
1399                 if (tp->t_pgrp != NULL)
1400                         *(int *)data = tp->t_pgrp->pg_id;
1401                 else
1402                         *(int *)data = NO_PID;
1403                 return (0);
1404         case TIOCGSID:
1405                 if (!tty_is_ctty(tp, td->td_proc))
1406                         return (ENOTTY);
1407
1408                 MPASS(tp->t_session);
1409                 *(int *)data = tp->t_session->s_sid;
1410                 return (0);
1411         case TIOCSCTTY: {
1412                 struct proc *p = td->td_proc;
1413
1414                 /* XXX: This looks awful. */
1415                 tty_unlock(tp);
1416                 sx_xlock(&proctree_lock);
1417                 tty_lock(tp);
1418
1419                 if (!SESS_LEADER(p)) {
1420                         /* Only the session leader may do this. */
1421                         sx_xunlock(&proctree_lock);
1422                         return (EPERM);
1423                 }
1424
1425                 if (tp->t_session != NULL && tp->t_session == p->p_session) {
1426                         /* This is already our controlling TTY. */
1427                         sx_xunlock(&proctree_lock);
1428                         return (0);
1429                 }
1430
1431                 if (!SESS_LEADER(p) || p->p_session->s_ttyvp != NULL ||
1432                     (tp->t_session != NULL && tp->t_session->s_ttyvp != NULL)) {
1433                         /*
1434                          * There is already a relation between a TTY and
1435                          * a session, or the caller is not the session
1436                          * leader.
1437                          *
1438                          * Allow the TTY to be stolen when the vnode is
1439                          * NULL, but the reference to the TTY is still
1440                          * active.
1441                          */
1442                         sx_xunlock(&proctree_lock);
1443                         return (EPERM);
1444                 }
1445
1446                 /* Connect the session to the TTY. */
1447                 tp->t_session = p->p_session;
1448                 tp->t_session->s_ttyp = tp;
1449                 tp->t_sessioncnt++;
1450                 sx_xunlock(&proctree_lock);
1451
1452                 /* Assign foreground process group. */
1453                 tp->t_pgrp = p->p_pgrp;
1454                 PROC_LOCK(p);
1455                 p->p_flag |= P_CONTROLT;
1456                 PROC_UNLOCK(p);
1457
1458                 return (0);
1459         }
1460         case TIOCSPGRP: {
1461                 struct pgrp *pg;
1462
1463                 /*
1464                  * XXX: Temporarily unlock the TTY to locate the process
1465                  * group. This code would be lot nicer if we would ever
1466                  * decompose proctree_lock.
1467                  */
1468                 tty_unlock(tp);
1469                 sx_slock(&proctree_lock);
1470                 pg = pgfind(*(int *)data);
1471                 if (pg != NULL)
1472                         PGRP_UNLOCK(pg);
1473                 if (pg == NULL || pg->pg_session != td->td_proc->p_session) {
1474                         sx_sunlock(&proctree_lock);
1475                         tty_lock(tp);
1476                         return (EPERM);
1477                 }
1478                 tty_lock(tp);
1479
1480                 /*
1481                  * Determine if this TTY is the controlling TTY after
1482                  * relocking the TTY.
1483                  */
1484                 if (!tty_is_ctty(tp, td->td_proc)) {
1485                         sx_sunlock(&proctree_lock);
1486                         return (ENOTTY);
1487                 }
1488                 tp->t_pgrp = pg;
1489                 sx_sunlock(&proctree_lock);
1490
1491                 /* Wake up the background process groups. */
1492                 cv_broadcast(&tp->t_bgwait);
1493                 return (0);
1494         }
1495         case TIOCFLUSH: {
1496                 int flags = *(int *)data;
1497
1498                 if (flags == 0)
1499                         flags = (FREAD|FWRITE);
1500                 else
1501                         flags &= (FREAD|FWRITE);
1502                 tty_flush(tp, flags);
1503                 return (0);
1504         }
1505         case TIOCDRAIN:
1506                 /* Drain TTY output. */
1507                 return tty_drain(tp);
1508         case TIOCCONS:
1509                 /* Set terminal as console TTY. */
1510                 if (*(int *)data) {
1511                         struct nameidata nd;
1512                         int vfslocked;
1513
1514                         /*
1515                          * XXX: TTY won't slip away, but constty would
1516                          * really need to be locked!
1517                          */
1518                         tty_unlock(tp);
1519
1520                         if (constty == tp) {
1521                                 tty_lock(tp);
1522                                 return (0);
1523                         }
1524                         if (constty != NULL) {
1525                                 tty_lock(tp);
1526                                 return (EBUSY);
1527                         }
1528                         /* XXX: allow disconnected constty's to be stolen! */
1529
1530                         /*
1531                          * Only allow this to work when the user can
1532                          * open /dev/console.
1533                          */
1534                         NDINIT(&nd, LOOKUP, FOLLOW|LOCKLEAF|MPSAFE,
1535                             UIO_SYSSPACE, "/dev/console", td);
1536                         if ((error = namei(&nd)) != 0) {
1537                                 tty_lock(tp);
1538                                 return (error);
1539                         }
1540                         vfslocked = NDHASGIANT(&nd);
1541                         NDFREE(&nd, NDF_ONLY_PNBUF);
1542
1543                         error = VOP_ACCESS(nd.ni_vp, VREAD, td->td_ucred, td);
1544                         vput(nd.ni_vp);
1545                         VFS_UNLOCK_GIANT(vfslocked);
1546                         if (error) {
1547                                 tty_lock(tp);
1548                                 return (error);
1549                         }
1550
1551                         constty_set(tp);
1552                         tty_lock(tp);
1553                 } else if (constty == tp) {
1554                         constty_clear();
1555                 }
1556                 return (0);
1557         case TIOCGWINSZ:
1558                 /* Obtain window size. */
1559                 bcopy(&tp->t_winsize, data, sizeof(struct winsize));
1560                 return (0);
1561         case TIOCSWINSZ:
1562                 /* Set window size. */
1563                 if (bcmp(&tp->t_winsize, data, sizeof(struct winsize)) == 0)
1564                         return (0);
1565                 bcopy(data, &tp->t_winsize, sizeof(struct winsize));
1566                 tty_signal_pgrp(tp, SIGWINCH);
1567                 return (0);
1568         case TIOCEXCL:
1569                 tp->t_flags |= TF_EXCLUDE;
1570                 return (0);
1571         case TIOCNXCL:
1572                 tp->t_flags &= ~TF_EXCLUDE;
1573                 return (0);
1574         case TIOCOUTQ:
1575                 *(unsigned int *)data = ttyoutq_bytesused(&tp->t_outq);
1576                 return (0);
1577         case TIOCSTOP:
1578                 tp->t_flags |= TF_STOPPED;
1579                 return (0);
1580         case TIOCSTART:
1581                 tp->t_flags &= ~TF_STOPPED;
1582                 ttydevsw_outwakeup(tp);
1583                 return (0);
1584         case TIOCSTAT:
1585                 tty_info(tp);
1586                 return (0);
1587         }
1588
1589 #ifdef COMPAT_43TTY
1590         return tty_ioctl_compat(tp, cmd, data, td);
1591 #else /* !COMPAT_43TTY */
1592         return (ENOIOCTL);
1593 #endif /* COMPAT_43TTY */
1594 }
1595
1596 int
1597 tty_ioctl(struct tty *tp, u_long cmd, void *data, struct thread *td)
1598 {
1599         int error;
1600
1601         tty_lock_assert(tp, MA_OWNED);
1602
1603         if (tty_gone(tp))
1604                 return (ENXIO);
1605         
1606         error = ttydevsw_ioctl(tp, cmd, data, td);
1607         if (error == ENOIOCTL)
1608                 error = tty_generic_ioctl(tp, cmd, data, td);
1609
1610         return (error);
1611 }
1612
1613 dev_t
1614 tty_udev(struct tty *tp)
1615 {
1616         if (tp->t_dev)
1617                 return dev2udev(tp->t_dev);
1618         else
1619                 return NODEV;
1620 }
1621
1622 int
1623 tty_checkoutq(struct tty *tp)
1624 {
1625
1626         /* 256 bytes should be enough to print a log message. */
1627         return (ttyoutq_bytesleft(&tp->t_outq) >= 256);
1628 }
1629
1630 void
1631 tty_hiwat_in_block(struct tty *tp)
1632 {
1633
1634         if ((tp->t_flags & TF_HIWAT_IN) == 0 &&
1635             tp->t_termios.c_iflag & IXOFF &&
1636             tp->t_termios.c_cc[VSTOP] != _POSIX_VDISABLE) {
1637                 /*
1638                  * Input flow control. Only enter the high watermark when we
1639                  * can successfully store the VSTOP character.
1640                  */
1641                 if (ttyoutq_write_nofrag(&tp->t_outq,
1642                     &tp->t_termios.c_cc[VSTOP], 1) == 0)
1643                         tp->t_flags |= TF_HIWAT_IN;
1644         } else {
1645                 /* No input flow control. */
1646                 tp->t_flags |= TF_HIWAT_IN;
1647         }
1648 }
1649
1650 void
1651 tty_hiwat_in_unblock(struct tty *tp)
1652 {
1653
1654         if ((tp->t_flags & TF_HIWAT_IN) == 0 &&
1655             tp->t_termios.c_iflag & IXOFF &&
1656             tp->t_termios.c_cc[VSTART] != _POSIX_VDISABLE) {
1657                 /*
1658                  * Input flow control. Only leave the high watermark when we
1659                  * can successfully store the VSTART character.
1660                  */
1661                 if (ttyoutq_write_nofrag(&tp->t_outq,
1662                     &tp->t_termios.c_cc[VSTART], 1) == 0)
1663                         tp->t_flags &= ~TF_HIWAT_IN;
1664         } else {
1665                 /* No input flow control. */
1666                 tp->t_flags &= ~TF_HIWAT_IN;
1667         }
1668
1669         if (!tty_gone(tp))
1670                 ttydevsw_inwakeup(tp);
1671 }
1672
1673 #include "opt_ddb.h"
1674 #ifdef DDB
1675 #include <ddb/ddb.h>
1676
1677 static struct {
1678         int flag;
1679         char val;
1680 } ttystates[] = {
1681 #if 0
1682         { TF_NOPREFIX,  'N' },
1683 #endif
1684         { TF_INITLOCK,  'I' },
1685         { TF_CALLOUT,   'C' },
1686
1687         /* Keep these together -> 'Oi' and 'Oo'. */
1688         { TF_OPENED,    'O' },
1689         { TF_OPENED_IN, 'i' },
1690         { TF_OPENED_OUT,'o' },
1691
1692         { TF_GONE,      'G' },
1693         { TF_OPENCLOSE, 'B' },
1694         { TF_ASYNC,     'Y' },
1695         { TF_LITERAL,   'L' },
1696
1697         /* Keep these together -> 'Hi' and 'Ho'. */
1698         { TF_HIWAT,     'H' },
1699         { TF_HIWAT_IN,  'i' },
1700         { TF_HIWAT_OUT, 'o' },
1701
1702         { TF_STOPPED,   'S' },
1703         { TF_EXCLUDE,   'X' },
1704         { TF_BYPASS,    'l' },
1705         { TF_ZOMBIE,    'Z' },
1706
1707         { 0,           '\0' },
1708 };
1709
1710 /* DDB command to show TTY statistics. */
1711 DB_SHOW_COMMAND(ttys, db_show_ttys)
1712 {
1713         struct tty *tp;
1714         size_t isiz, osiz;
1715         int i, j;
1716
1717         /* Make the output look like `pstat -t'. */
1718         db_printf("      LINE   INQ  CAN  LIN  LOW  OUTQ  USE  LOW   "
1719             "COL  SESS  PGID STATE\n");
1720
1721         TAILQ_FOREACH(tp, &tty_list, t_list) {
1722                 isiz = tp->t_inq.ti_nblocks * TTYINQ_DATASIZE;
1723                 osiz = tp->t_outq.to_nblocks * TTYOUTQ_DATASIZE;
1724
1725                 db_printf("%10s %5zu %4u %4u %4zu %5zu %4u %4zu %5u %5d %5d ",
1726                     tty_devname(tp),
1727                     isiz,
1728                     tp->t_inq.ti_linestart - tp->t_inq.ti_begin,
1729                     tp->t_inq.ti_end - tp->t_inq.ti_linestart,
1730                     isiz - tp->t_inlow,
1731                     osiz,
1732                     tp->t_outq.to_end - tp->t_outq.to_begin,
1733                     osiz - tp->t_outlow,
1734                     tp->t_column,
1735                     tp->t_session ? tp->t_session->s_sid : 0,
1736                     tp->t_pgrp ? tp->t_pgrp->pg_id : 0);
1737
1738                 /* Flag bits. */
1739                 for (i = j = 0; ttystates[i].flag; i++)
1740                         if (tp->t_flags & ttystates[i].flag) {
1741                                 db_printf("%c", ttystates[i].val);
1742                                 j++;
1743                         }
1744                 if (j == 0)
1745                         db_printf("-");
1746                 db_printf("\n");
1747         }
1748 }
1749 #endif /* DDB */