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