tty.c revision 183922
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: head/sys/kern/tty.c 183922 2008-10-15 16:58:35Z ed $");
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/file.h>
40#include <sys/filio.h>
41#ifdef COMPAT_43TTY
42#include <sys/ioctl_compat.h>
43#endif /* COMPAT_43TTY */
44#include <sys/kernel.h>
45#include <sys/limits.h>
46#include <sys/malloc.h>
47#include <sys/mount.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
67static MALLOC_DEFINE(M_TTY, "tty", "tty device");
68
69static void tty_rel_free(struct tty *tp);
70
71static TAILQ_HEAD(, tty) tty_list = TAILQ_HEAD_INITIALIZER(tty_list);
72static struct sx tty_list_sx;
73SX_SYSINIT(tty_list, &tty_list_sx, "tty list");
74static 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#define	TTYBUF_MAX	65536
96
97static void
98tty_watermarks(struct tty *tp)
99{
100	size_t bs;
101
102	/* Provide an input buffer for 0.2 seconds of data. */
103	bs = MIN(tp->t_termios.c_ispeed / 5, TTYBUF_MAX);
104	ttyinq_setsize(&tp->t_inq, tp, bs);
105
106	/* Set low watermark at 10% (when 90% is available). */
107	tp->t_inlow = (ttyinq_getsize(&tp->t_inq) * 9) / 10;
108
109	/* Provide an ouput buffer for 0.2 seconds of data. */
110	bs = MIN(tp->t_termios.c_ospeed / 5, TTYBUF_MAX);
111	ttyoutq_setsize(&tp->t_outq, tp, bs);
112
113	/* Set low watermark at 10% (when 90% is available). */
114	tp->t_outlow = (ttyoutq_getsize(&tp->t_outq) * 9) / 10;
115}
116
117static int
118tty_drain(struct tty *tp)
119{
120	int error;
121
122	while (ttyoutq_bytesused(&tp->t_outq) > 0) {
123		ttydevsw_outwakeup(tp);
124		/* Could be handled synchronously. */
125		if (ttyoutq_bytesused(&tp->t_outq) == 0)
126			return (0);
127
128		/* Wait for data to be drained. */
129		error = tty_wait(tp, &tp->t_outwait);
130		if (error)
131			return (error);
132	}
133
134	return (0);
135}
136
137/*
138 * Though ttydev_enter() and ttydev_leave() seem to be related, they
139 * don't have to be used together. ttydev_enter() is used by the cdev
140 * operations to prevent an actual operation from being processed when
141 * the TTY has been abandoned. ttydev_leave() is used by ttydev_open()
142 * and ttydev_close() to determine whether per-TTY data should be
143 * deallocated.
144 */
145
146static __inline int
147ttydev_enter(struct tty *tp)
148{
149	tty_lock(tp);
150
151	if (tty_gone(tp) || !tty_opened(tp)) {
152		/* Device is already gone. */
153		tty_unlock(tp);
154		return (ENXIO);
155	}
156
157	return (0);
158}
159
160static void
161ttydev_leave(struct tty *tp)
162{
163	tty_lock_assert(tp, MA_OWNED);
164
165	if (tty_opened(tp) || tp->t_flags & TF_OPENCLOSE) {
166		/* Device is still opened somewhere. */
167		tty_unlock(tp);
168		return;
169	}
170
171	tp->t_flags |= TF_OPENCLOSE;
172
173	/* Stop asynchronous I/O. */
174	funsetown(&tp->t_sigio);
175
176	/* Remove console TTY. */
177	if (constty == tp)
178		constty_clear();
179
180	/* Drain any output. */
181	MPASS((tp->t_flags & TF_STOPPED) == 0);
182	if (!tty_gone(tp))
183		tty_drain(tp);
184
185	ttydisc_close(tp);
186
187	/* Destroy associated buffers already. */
188	ttyinq_free(&tp->t_inq);
189	tp->t_inlow = 0;
190	ttyoutq_free(&tp->t_outq);
191	tp->t_outlow = 0;
192
193	knlist_clear(&tp->t_inpoll.si_note, 1);
194	knlist_clear(&tp->t_outpoll.si_note, 1);
195
196	if (!tty_gone(tp))
197		ttydevsw_close(tp);
198
199	tp->t_flags &= ~TF_OPENCLOSE;
200	tty_rel_free(tp);
201}
202
203/*
204 * Operations that are exposed through the character device in /dev.
205 */
206static int
207ttydev_open(struct cdev *dev, int oflags, int devtype, struct thread *td)
208{
209	struct tty *tp = dev->si_drv1;
210	int error = 0;
211
212	/* Disallow access when the TTY belongs to a different prison. */
213	if (dev->si_cred != NULL &&
214	    dev->si_cred->cr_prison != td->td_ucred->cr_prison &&
215	    priv_check(td, PRIV_TTY_PRISON)) {
216		return (EPERM);
217	}
218
219	tty_lock(tp);
220	if (tty_gone(tp)) {
221		/* Device is already gone. */
222		tty_unlock(tp);
223		return (ENXIO);
224	}
225	/*
226	 * Prevent the TTY from being opened when being torn down or
227	 * built up by unrelated processes.
228	 */
229	if (tp->t_flags & TF_OPENCLOSE) {
230		tty_unlock(tp);
231		return (EBUSY);
232	}
233	tp->t_flags |= TF_OPENCLOSE;
234
235	/*
236	 * Make sure the "tty" and "cua" device cannot be opened at the
237	 * same time.
238	 */
239	if (TTY_CALLOUT(tp, dev)) {
240		if (tp->t_flags & TF_OPENED_IN) {
241			error = EBUSY;
242			goto done;
243		}
244	} else {
245		if (tp->t_flags & TF_OPENED_OUT) {
246			error = EBUSY;
247			goto done;
248		}
249	}
250
251	if (tp->t_flags & TF_EXCLUDE && priv_check(td, PRIV_TTY_EXCLUSIVE)) {
252		error = EBUSY;
253		goto done;
254	}
255
256	if (!tty_opened(tp)) {
257		/* Set proper termios flags. */
258		if (TTY_CALLOUT(tp, dev)) {
259			tp->t_termios = tp->t_termios_init_out;
260		} else {
261			tp->t_termios = tp->t_termios_init_in;
262		}
263		ttydevsw_param(tp, &tp->t_termios);
264
265		ttydevsw_modem(tp, SER_DTR|SER_RTS, 0);
266
267		error = ttydevsw_open(tp);
268		if (error != 0)
269			goto done;
270
271		ttydisc_open(tp);
272		tty_watermarks(tp);
273	}
274
275	/* Wait for Carrier Detect. */
276	if (!TTY_CALLOUT(tp, dev) && (oflags & O_NONBLOCK) == 0 &&
277	    (tp->t_termios.c_cflag & CLOCAL) == 0) {
278		while ((ttydevsw_modem(tp, 0, 0) & SER_DCD) == 0) {
279			error = tty_wait(tp, &tp->t_dcdwait);
280			if (error != 0)
281				goto done;
282		}
283	}
284
285	if (TTY_CALLOUT(tp, dev)) {
286		tp->t_flags |= TF_OPENED_OUT;
287	} else {
288		tp->t_flags |= TF_OPENED_IN;
289	}
290
291done:	tp->t_flags &= ~TF_OPENCLOSE;
292	ttydev_leave(tp);
293
294	return (error);
295}
296
297static int
298ttydev_close(struct cdev *dev, int fflag, int devtype, struct thread *td)
299{
300	struct tty *tp = dev->si_drv1;
301
302	tty_lock(tp);
303
304	/*
305	 * This can only be called once. The callin and the callout
306	 * devices cannot be opened at the same time.
307	 */
308	MPASS((tp->t_flags & TF_OPENED) != TF_OPENED);
309	tp->t_flags &= ~(TF_OPENED|TF_EXCLUDE|TF_STOPPED);
310
311	/* Properly wake up threads that are stuck - revoke(). */
312	tp->t_revokecnt++;
313	tty_wakeup(tp, FREAD|FWRITE);
314	cv_broadcast(&tp->t_bgwait);
315
316	ttydev_leave(tp);
317
318	return (0);
319}
320
321static __inline int
322tty_is_ctty(struct tty *tp, struct proc *p)
323{
324	tty_lock_assert(tp, MA_OWNED);
325
326	return (p->p_session == tp->t_session && p->p_flag & P_CONTROLT);
327}
328
329static int
330tty_wait_background(struct tty *tp, struct thread *td, int sig)
331{
332	struct proc *p = td->td_proc;
333	struct pgrp *pg;
334	int error;
335
336	MPASS(sig == SIGTTIN || sig == SIGTTOU);
337	tty_lock_assert(tp, MA_OWNED);
338
339	for (;;) {
340		PROC_LOCK(p);
341		/*
342		 * The process should only sleep, when:
343		 * - This terminal is the controling terminal
344		 * - Its process group is not the foreground process
345		 *   group
346		 * - The parent process isn't waiting for the child to
347		 *   exit
348		 * - the signal to send to the process isn't masked
349		 */
350		if (!tty_is_ctty(tp, p) ||
351		    p->p_pgrp == tp->t_pgrp || p->p_flag & P_PPWAIT ||
352		    SIGISMEMBER(p->p_sigacts->ps_sigignore, sig) ||
353		    SIGISMEMBER(td->td_sigmask, sig)) {
354			/* Allow the action to happen. */
355			PROC_UNLOCK(p);
356			return (0);
357		}
358
359		/*
360		 * Send the signal and sleep until we're the new
361		 * foreground process group.
362		 */
363		pg = p->p_pgrp;
364		PROC_UNLOCK(p);
365		if (pg->pg_jobc == 0)
366			return (EIO);
367		PGRP_LOCK(pg);
368		pgsignal(pg, sig, 1);
369		PGRP_UNLOCK(pg);
370
371		error = tty_wait(tp, &tp->t_bgwait);
372		if (error)
373			return (error);
374	}
375}
376
377static int
378ttydev_read(struct cdev *dev, struct uio *uio, int ioflag)
379{
380	struct tty *tp = dev->si_drv1;
381	int error;
382
383	error = ttydev_enter(tp);
384	if (error)
385		goto done;
386
387	error = tty_wait_background(tp, curthread, SIGTTIN);
388	if (error) {
389		tty_unlock(tp);
390		goto done;
391	}
392
393	error = ttydisc_read(tp, uio, ioflag);
394	tty_unlock(tp);
395
396	/*
397	 * The read() call should not throw an error when the device is
398	 * being destroyed. Silently convert it to an EOF.
399	 */
400done:	if (error == ENXIO)
401		error = 0;
402	return (error);
403}
404
405static int
406ttydev_write(struct cdev *dev, struct uio *uio, int ioflag)
407{
408	struct tty *tp = dev->si_drv1;
409	int error;
410
411	error = ttydev_enter(tp);
412	if (error)
413		return (error);
414
415	if (tp->t_termios.c_lflag & TOSTOP) {
416		error = tty_wait_background(tp, curthread, SIGTTOU);
417		if (error) {
418			tty_unlock(tp);
419			return (error);
420		}
421	}
422
423	error = ttydisc_write(tp, uio, ioflag);
424	tty_unlock(tp);
425
426	return (error);
427}
428
429static int
430ttydev_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);
482done:	tty_unlock(tp);
483
484	return (error);
485}
486
487static int
488ttydev_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	tty_unlock(tp);
522
523	return (revents);
524}
525
526static int
527ttydev_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	tty_unlock(tp);
539
540	return (error);
541}
542
543/*
544 * kqueue support.
545 */
546
547static void
548tty_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
555static int
556tty_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
571static void
572tty_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
579static int
580tty_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
595static struct filterops tty_kqops_read =
596    { 1, NULL, tty_kqops_read_detach, tty_kqops_read_event };
597static struct filterops tty_kqops_write =
598    { 1, NULL, tty_kqops_write_detach, tty_kqops_write_event };
599
600static int
601ttydev_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	tty_unlock(tp);
627	return (error);
628}
629
630static 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
648static int
649ttyil_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
662static int
663ttyil_close(struct cdev *dev, int flag, int mode, struct thread *td)
664{
665	return (0);
666}
667
668static int
669ttyil_rdwr(struct cdev *dev, struct uio *uio, int ioflag)
670{
671	return (ENODEV);
672}
673
674static int
675ttyil_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
709done:	tty_unlock(tp);
710	return (error);
711}
712
713static 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
724static void
725tty_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
740void
741tty_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
761static int
762ttydevsw_defopen(struct tty *tp)
763{
764
765	return (0);
766}
767
768static void
769ttydevsw_defclose(struct tty *tp)
770{
771}
772
773static void
774ttydevsw_defoutwakeup(struct tty *tp)
775{
776
777	panic("Terminal device has output, while not implemented");
778}
779
780static void
781ttydevsw_definwakeup(struct tty *tp)
782{
783}
784
785static int
786ttydevsw_defioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td)
787{
788
789	return (ENOIOCTL);
790}
791
792static int
793ttydevsw_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
802static int
803ttydevsw_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
810static int
811ttydevsw_defmmap(struct tty *tp, vm_offset_t offset, vm_paddr_t *paddr,
812    int nprot)
813{
814
815	return (-1);
816}
817
818static void
819ttydevsw_defpktnotify(struct tty *tp, char event)
820{
821}
822
823static void
824ttydevsw_deffree(void *softc)
825{
826
827	panic("Terminal device freed without a free-handler");
828}
829
830/*
831 * TTY allocation and deallocation. TTY devices can be deallocated when
832 * the driver doesn't use it anymore, when the TTY isn't a session's
833 * controlling TTY and when the device node isn't opened through devfs.
834 */
835
836struct tty *
837tty_alloc(struct ttydevsw *tsw, void *sc, struct mtx *mutex)
838{
839	struct tty *tp;
840
841	/* Make sure the driver defines all routines. */
842#define PATCH_FUNC(x) do {				\
843	if (tsw->tsw_ ## x == NULL)			\
844		tsw->tsw_ ## x = ttydevsw_def ## x;	\
845} while (0)
846	PATCH_FUNC(open);
847	PATCH_FUNC(close);
848	PATCH_FUNC(outwakeup);
849	PATCH_FUNC(inwakeup);
850	PATCH_FUNC(ioctl);
851	PATCH_FUNC(param);
852	PATCH_FUNC(modem);
853	PATCH_FUNC(mmap);
854	PATCH_FUNC(pktnotify);
855	PATCH_FUNC(free);
856#undef PATCH_FUNC
857
858	tp = malloc(sizeof(struct tty), M_TTY, M_WAITOK|M_ZERO);
859	tp->t_devsw = tsw;
860	tp->t_devswsoftc = sc;
861	tp->t_flags = tsw->tsw_flags;
862
863	tty_init_termios(tp);
864
865	cv_init(&tp->t_inwait, "tty input");
866	cv_init(&tp->t_outwait, "tty output");
867	cv_init(&tp->t_bgwait, "tty background");
868	cv_init(&tp->t_dcdwait, "tty dcd");
869
870	ttyinq_init(&tp->t_inq);
871	ttyoutq_init(&tp->t_outq);
872
873	/* Allow drivers to use a custom mutex to lock the TTY. */
874	if (mutex != NULL) {
875		tp->t_mtx = mutex;
876	} else {
877		tp->t_mtx = &tp->t_mtxobj;
878		mtx_init(&tp->t_mtxobj, "tty lock", NULL, MTX_DEF);
879	}
880
881	knlist_init(&tp->t_inpoll.si_note, tp->t_mtx, NULL, NULL, NULL);
882	knlist_init(&tp->t_outpoll.si_note, tp->t_mtx, NULL, NULL, NULL);
883
884	sx_xlock(&tty_list_sx);
885	TAILQ_INSERT_TAIL(&tty_list, tp, t_list);
886	tty_list_count++;
887	sx_xunlock(&tty_list_sx);
888
889	return (tp);
890}
891
892static void
893tty_dealloc(void *arg)
894{
895	struct tty *tp = arg;
896
897	sx_xlock(&tty_list_sx);
898	TAILQ_REMOVE(&tty_list, tp, t_list);
899	tty_list_count--;
900	sx_xunlock(&tty_list_sx);
901
902	/* Make sure we haven't leaked buffers. */
903	MPASS(ttyinq_getsize(&tp->t_inq) == 0);
904	MPASS(ttyoutq_getsize(&tp->t_outq) == 0);
905
906	knlist_destroy(&tp->t_inpoll.si_note);
907	knlist_destroy(&tp->t_outpoll.si_note);
908
909	cv_destroy(&tp->t_inwait);
910	cv_destroy(&tp->t_outwait);
911	cv_destroy(&tp->t_bgwait);
912	cv_destroy(&tp->t_dcdwait);
913
914	if (tp->t_mtx == &tp->t_mtxobj)
915		mtx_destroy(&tp->t_mtxobj);
916	ttydevsw_free(tp);
917	free(tp, M_TTY);
918}
919
920static void
921tty_rel_free(struct tty *tp)
922{
923	struct cdev *dev;
924
925	tty_lock_assert(tp, MA_OWNED);
926
927#define	TF_ACTIVITY	(TF_GONE|TF_OPENED|TF_HOOK|TF_OPENCLOSE)
928	if (tp->t_sessioncnt != 0 || (tp->t_flags & TF_ACTIVITY) != TF_GONE) {
929		/* TTY is still in use. */
930		tty_unlock(tp);
931		return;
932	}
933
934	/* TTY can be deallocated. */
935	dev = tp->t_dev;
936	tp->t_dev = NULL;
937	tty_unlock(tp);
938
939	destroy_dev_sched_cb(dev, tty_dealloc, tp);
940}
941
942void
943tty_rel_pgrp(struct tty *tp, struct pgrp *pg)
944{
945	MPASS(tp->t_sessioncnt > 0);
946	tty_lock_assert(tp, MA_OWNED);
947
948	if (tp->t_pgrp == pg)
949		tp->t_pgrp = NULL;
950
951	tty_unlock(tp);
952}
953
954void
955tty_rel_sess(struct tty *tp, struct session *sess)
956{
957	MPASS(tp->t_sessioncnt > 0);
958
959	/* Current session has left. */
960	if (tp->t_session == sess) {
961		tp->t_session = NULL;
962		MPASS(tp->t_pgrp == NULL);
963	}
964	tp->t_sessioncnt--;
965	tty_rel_free(tp);
966}
967
968void
969tty_rel_gone(struct tty *tp)
970{
971	MPASS(!tty_gone(tp));
972
973	/* Simulate carrier removal. */
974	ttydisc_modem(tp, 0);
975
976	/* Wake up all blocked threads. */
977	tty_wakeup(tp, FREAD|FWRITE);
978	cv_broadcast(&tp->t_bgwait);
979	cv_broadcast(&tp->t_dcdwait);
980
981	tp->t_flags |= TF_GONE;
982	tty_rel_free(tp);
983}
984
985/*
986 * Exposing information about current TTY's through sysctl
987 */
988
989static void
990tty_to_xtty(struct tty *tp, struct xtty *xt)
991{
992	tty_lock_assert(tp, MA_OWNED);
993
994	xt->xt_size = sizeof(struct xtty);
995	xt->xt_insize = ttyinq_getsize(&tp->t_inq);
996	xt->xt_incc = ttyinq_bytescanonicalized(&tp->t_inq);
997	xt->xt_inlc = ttyinq_bytesline(&tp->t_inq);
998	xt->xt_inlow = tp->t_inlow;
999	xt->xt_outsize = ttyoutq_getsize(&tp->t_outq);
1000	xt->xt_outcc = ttyoutq_bytesused(&tp->t_outq);
1001	xt->xt_outlow = tp->t_outlow;
1002	xt->xt_column = tp->t_column;
1003	xt->xt_pgid = tp->t_pgrp ? tp->t_pgrp->pg_id : 0;
1004	xt->xt_sid = tp->t_session ? tp->t_session->s_sid : 0;
1005	xt->xt_flags = tp->t_flags;
1006	xt->xt_dev = tp->t_dev ? dev2udev(tp->t_dev) : NODEV;
1007}
1008
1009static int
1010sysctl_kern_ttys(SYSCTL_HANDLER_ARGS)
1011{
1012	unsigned long lsize;
1013	struct xtty *xtlist, *xt;
1014	struct tty *tp;
1015	int error;
1016
1017	sx_slock(&tty_list_sx);
1018	lsize = tty_list_count * sizeof(struct xtty);
1019	if (lsize == 0) {
1020		sx_sunlock(&tty_list_sx);
1021		return (0);
1022	}
1023
1024	xtlist = xt = malloc(lsize, M_TEMP, M_WAITOK);
1025
1026	TAILQ_FOREACH(tp, &tty_list, t_list) {
1027		tty_lock(tp);
1028		tty_to_xtty(tp, xt);
1029		tty_unlock(tp);
1030		xt++;
1031	}
1032	sx_sunlock(&tty_list_sx);
1033
1034	error = SYSCTL_OUT(req, xtlist, lsize);
1035	free(xtlist, M_TEMP);
1036	return (error);
1037}
1038
1039SYSCTL_PROC(_kern, OID_AUTO, ttys, CTLTYPE_OPAQUE|CTLFLAG_RD,
1040	0, 0, sysctl_kern_ttys, "S,xtty", "List of TTYs");
1041
1042/*
1043 * Device node creation. Device has been set up, now we can expose it to
1044 * the user.
1045 */
1046
1047void
1048tty_makedev(struct tty *tp, struct ucred *cred, const char *fmt, ...)
1049{
1050	va_list ap;
1051	struct cdev *dev;
1052	const char *prefix = "tty";
1053	char name[SPECNAMELEN - 3]; /* for "tty" and "cua". */
1054	uid_t uid;
1055	gid_t gid;
1056	mode_t mode;
1057
1058	/* Remove "tty" prefix from devices like PTY's. */
1059	if (tp->t_flags & TF_NOPREFIX)
1060		prefix = "";
1061
1062	va_start(ap, fmt);
1063	vsnrprintf(name, sizeof name, 32, fmt, ap);
1064	va_end(ap);
1065
1066	if (cred == NULL) {
1067		/* System device. */
1068		uid = UID_ROOT;
1069		gid = GID_WHEEL;
1070		mode = S_IRUSR|S_IWUSR;
1071	} else {
1072		/* User device. */
1073		uid = cred->cr_ruid;
1074		gid = GID_TTY;
1075		mode = S_IRUSR|S_IWUSR|S_IWGRP;
1076	}
1077
1078	/* Master call-in device. */
1079	dev = make_dev_cred(&ttydev_cdevsw, 0, cred,
1080	    uid, gid, mode, "%s%s", prefix, name);
1081	dev->si_drv1 = tp;
1082	tp->t_dev = dev;
1083
1084	/* Slave call-in devices. */
1085	if (tp->t_flags & TF_INITLOCK) {
1086		dev = make_dev_cred(&ttyil_cdevsw, 0, cred,
1087		    uid, gid, mode, "%s%s.init", prefix, name);
1088		dev_depends(tp->t_dev, dev);
1089		dev->si_drv1 = tp;
1090		dev->si_drv2 = &tp->t_termios_init_in;
1091
1092		dev = make_dev_cred(&ttyil_cdevsw, 0, cred,
1093		    uid, gid, mode, "%s%s.lock", prefix, name);
1094		dev_depends(tp->t_dev, dev);
1095		dev->si_drv1 = tp;
1096		dev->si_drv2 = &tp->t_termios_lock_in;
1097	}
1098
1099	/* Call-out devices. */
1100	if (tp->t_flags & TF_CALLOUT) {
1101		dev = make_dev_cred(&ttydev_cdevsw, 0, cred,
1102		    UID_UUCP, GID_DIALER, 0660, "cua%s", name);
1103		dev_depends(tp->t_dev, dev);
1104		dev->si_drv1 = tp;
1105
1106		/* Slave call-out devices. */
1107		if (tp->t_flags & TF_INITLOCK) {
1108			dev = make_dev_cred(&ttyil_cdevsw, 0, cred,
1109			    UID_UUCP, GID_DIALER, 0660, "cua%s.init", name);
1110			dev_depends(tp->t_dev, dev);
1111			dev->si_drv1 = tp;
1112			dev->si_drv2 = &tp->t_termios_init_out;
1113
1114			dev = make_dev_cred(&ttyil_cdevsw, 0, cred,
1115			    UID_UUCP, GID_DIALER, 0660, "cua%s.lock", name);
1116			dev_depends(tp->t_dev, dev);
1117			dev->si_drv1 = tp;
1118			dev->si_drv2 = &tp->t_termios_lock_out;
1119		}
1120	}
1121}
1122
1123/*
1124 * Signalling processes.
1125 */
1126
1127void
1128tty_signal_sessleader(struct tty *tp, int sig)
1129{
1130	struct proc *p;
1131
1132	tty_lock_assert(tp, MA_OWNED);
1133	MPASS(sig >= 1 && sig < NSIG);
1134
1135	/* Make signals start output again. */
1136	tp->t_flags &= ~TF_STOPPED;
1137
1138	if (tp->t_session != NULL && tp->t_session->s_leader != NULL) {
1139		p = tp->t_session->s_leader;
1140		PROC_LOCK(p);
1141		psignal(p, sig);
1142		PROC_UNLOCK(p);
1143	}
1144}
1145
1146void
1147tty_signal_pgrp(struct tty *tp, int sig)
1148{
1149	tty_lock_assert(tp, MA_OWNED);
1150	MPASS(sig >= 1 && sig < NSIG);
1151
1152	/* Make signals start output again. */
1153	tp->t_flags &= ~TF_STOPPED;
1154
1155	if (sig == SIGINFO && !(tp->t_termios.c_lflag & NOKERNINFO))
1156		tty_info(tp);
1157	if (tp->t_pgrp != NULL) {
1158		PGRP_LOCK(tp->t_pgrp);
1159		pgsignal(tp->t_pgrp, sig, 1);
1160		PGRP_UNLOCK(tp->t_pgrp);
1161	}
1162}
1163
1164void
1165tty_wakeup(struct tty *tp, int flags)
1166{
1167	if (tp->t_flags & TF_ASYNC && tp->t_sigio != NULL)
1168		pgsigio(&tp->t_sigio, SIGIO, (tp->t_session != NULL));
1169
1170	if (flags & FWRITE) {
1171		cv_broadcast(&tp->t_outwait);
1172		selwakeup(&tp->t_outpoll);
1173		KNOTE_LOCKED(&tp->t_outpoll.si_note, 0);
1174	}
1175	if (flags & FREAD) {
1176		cv_broadcast(&tp->t_inwait);
1177		selwakeup(&tp->t_inpoll);
1178		KNOTE_LOCKED(&tp->t_inpoll.si_note, 0);
1179	}
1180}
1181
1182int
1183tty_wait(struct tty *tp, struct cv *cv)
1184{
1185	int error;
1186	int revokecnt = tp->t_revokecnt;
1187
1188#if 0
1189	/* XXX: /dev/console also picks up Giant. */
1190	tty_lock_assert(tp, MA_OWNED|MA_NOTRECURSED);
1191#endif
1192	tty_lock_assert(tp, MA_OWNED);
1193	MPASS(!tty_gone(tp));
1194
1195	error = cv_wait_sig(cv, tp->t_mtx);
1196
1197	/* Restart the system call when we may have been revoked. */
1198	if (tp->t_revokecnt != revokecnt)
1199		return (ERESTART);
1200
1201	/* Bail out when the device slipped away. */
1202	if (tty_gone(tp))
1203		return (ENXIO);
1204
1205	return (error);
1206}
1207
1208int
1209tty_timedwait(struct tty *tp, struct cv *cv, int hz)
1210{
1211	int error;
1212	int revokecnt = tp->t_revokecnt;
1213
1214#if 0
1215	/* XXX: /dev/console also picks up Giant. */
1216	tty_lock_assert(tp, MA_OWNED|MA_NOTRECURSED);
1217#endif
1218	tty_lock_assert(tp, MA_OWNED);
1219	MPASS(!tty_gone(tp));
1220
1221	error = cv_timedwait_sig(cv, tp->t_mtx, hz);
1222
1223	/* Restart the system call when we may have been revoked. */
1224	if (tp->t_revokecnt != revokecnt)
1225		return (ERESTART);
1226
1227	/* Bail out when the device slipped away. */
1228	if (tty_gone(tp))
1229		return (ENXIO);
1230
1231	return (error);
1232}
1233
1234void
1235tty_flush(struct tty *tp, int flags)
1236{
1237	if (flags & FWRITE) {
1238		tp->t_flags &= ~TF_HIWAT_OUT;
1239		ttyoutq_flush(&tp->t_outq);
1240		tty_wakeup(tp, FWRITE);
1241		ttydevsw_pktnotify(tp, TIOCPKT_FLUSHWRITE);
1242	}
1243	if (flags & FREAD) {
1244		tty_hiwat_in_unblock(tp);
1245		ttyinq_flush(&tp->t_inq);
1246		ttydevsw_inwakeup(tp);
1247		ttydevsw_pktnotify(tp, TIOCPKT_FLUSHREAD);
1248	}
1249}
1250
1251static int
1252tty_generic_ioctl(struct tty *tp, u_long cmd, void *data, struct thread *td)
1253{
1254	int error;
1255
1256	switch (cmd) {
1257	/*
1258	 * Modem commands.
1259	 * The SER_* and TIOCM_* flags are the same, but one bit
1260	 * shifted. I don't know why.
1261	 */
1262	case TIOCSDTR:
1263		ttydevsw_modem(tp, SER_DTR, 0);
1264		return (0);
1265	case TIOCCDTR:
1266		ttydevsw_modem(tp, 0, SER_DTR);
1267		return (0);
1268	case TIOCMSET: {
1269		int bits = *(int *)data;
1270		ttydevsw_modem(tp,
1271		    (bits & (TIOCM_DTR | TIOCM_RTS)) >> 1,
1272		    ((~bits) & (TIOCM_DTR | TIOCM_RTS)) >> 1);
1273		return (0);
1274	}
1275	case TIOCMBIS: {
1276		int bits = *(int *)data;
1277		ttydevsw_modem(tp, (bits & (TIOCM_DTR | TIOCM_RTS)) >> 1, 0);
1278		return (0);
1279	}
1280	case TIOCMBIC: {
1281		int bits = *(int *)data;
1282		ttydevsw_modem(tp, 0, (bits & (TIOCM_DTR | TIOCM_RTS)) >> 1);
1283		return (0);
1284	}
1285	case TIOCMGET:
1286		*(int *)data = TIOCM_LE + (ttydevsw_modem(tp, 0, 0) << 1);
1287		return (0);
1288
1289	case FIOASYNC:
1290		if (*(int *)data)
1291			tp->t_flags |= TF_ASYNC;
1292		else
1293			tp->t_flags &= ~TF_ASYNC;
1294		return (0);
1295	case FIONBIO:
1296		/* This device supports non-blocking operation. */
1297		return (0);
1298	case FIONREAD:
1299		*(int *)data = ttyinq_bytescanonicalized(&tp->t_inq);
1300		return (0);
1301	case FIOSETOWN:
1302		if (tp->t_session != NULL && !tty_is_ctty(tp, td->td_proc))
1303			/* Not allowed to set ownership. */
1304			return (ENOTTY);
1305
1306		/* Temporarily unlock the TTY to set ownership. */
1307		tty_unlock(tp);
1308		error = fsetown(*(int *)data, &tp->t_sigio);
1309		tty_lock(tp);
1310		return (error);
1311	case FIOGETOWN:
1312		if (tp->t_session != NULL && !tty_is_ctty(tp, td->td_proc))
1313			/* Not allowed to set ownership. */
1314			return (ENOTTY);
1315
1316		/* Get ownership. */
1317		*(int *)data = fgetown(&tp->t_sigio);
1318		return (0);
1319	case TIOCGETA:
1320		/* Obtain terminal flags through tcgetattr(). */
1321		bcopy(&tp->t_termios, data, sizeof(struct termios));
1322		return (0);
1323	case TIOCSETA:
1324	case TIOCSETAW:
1325	case TIOCSETAF: {
1326		struct termios *t = data;
1327
1328		/*
1329		 * Who makes up these funny rules? According to POSIX,
1330		 * input baud rate is set equal to the output baud rate
1331		 * when zero.
1332		 */
1333		if (t->c_ispeed == 0)
1334			t->c_ispeed = t->c_ospeed;
1335
1336		/* Discard any unsupported bits. */
1337		t->c_iflag &= TTYSUP_IFLAG;
1338		t->c_oflag &= TTYSUP_OFLAG;
1339		t->c_lflag &= TTYSUP_LFLAG;
1340		t->c_cflag &= TTYSUP_CFLAG;
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 & ~CIGNORE;
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
1390		/*
1391		 * For packet mode: notify the PTY consumer that VSTOP
1392		 * and VSTART may have been changed.
1393		 */
1394		if (tp->t_termios.c_iflag & IXON &&
1395		    tp->t_termios.c_cc[VSTOP] == CTRL('S') &&
1396		    tp->t_termios.c_cc[VSTART] == CTRL('Q'))
1397			ttydevsw_pktnotify(tp, TIOCPKT_DOSTOP);
1398		else
1399			ttydevsw_pktnotify(tp, TIOCPKT_NOSTOP);
1400		return (0);
1401	}
1402	case TIOCGETD:
1403		/* For compatibility - we only support TTYDISC. */
1404		*(int *)data = TTYDISC;
1405		return (0);
1406	case TIOCGPGRP:
1407		if (!tty_is_ctty(tp, td->td_proc))
1408			return (ENOTTY);
1409
1410		if (tp->t_pgrp != NULL)
1411			*(int *)data = tp->t_pgrp->pg_id;
1412		else
1413			*(int *)data = NO_PID;
1414		return (0);
1415	case TIOCGSID:
1416		if (!tty_is_ctty(tp, td->td_proc))
1417			return (ENOTTY);
1418
1419		MPASS(tp->t_session);
1420		*(int *)data = tp->t_session->s_sid;
1421		return (0);
1422	case TIOCSCTTY: {
1423		struct proc *p = td->td_proc;
1424
1425		/* XXX: This looks awful. */
1426		tty_unlock(tp);
1427		sx_xlock(&proctree_lock);
1428		tty_lock(tp);
1429
1430		if (!SESS_LEADER(p)) {
1431			/* Only the session leader may do this. */
1432			sx_xunlock(&proctree_lock);
1433			return (EPERM);
1434		}
1435
1436		if (tp->t_session != NULL && tp->t_session == p->p_session) {
1437			/* This is already our controlling TTY. */
1438			sx_xunlock(&proctree_lock);
1439			return (0);
1440		}
1441
1442		if (!SESS_LEADER(p) || p->p_session->s_ttyvp != NULL ||
1443		    (tp->t_session != NULL && tp->t_session->s_ttyvp != NULL)) {
1444			/*
1445			 * There is already a relation between a TTY and
1446			 * a session, or the caller is not the session
1447			 * leader.
1448			 *
1449			 * Allow the TTY to be stolen when the vnode is
1450			 * NULL, but the reference to the TTY is still
1451			 * active.
1452			 */
1453			sx_xunlock(&proctree_lock);
1454			return (EPERM);
1455		}
1456
1457		/* Connect the session to the TTY. */
1458		tp->t_session = p->p_session;
1459		tp->t_session->s_ttyp = tp;
1460		tp->t_sessioncnt++;
1461		sx_xunlock(&proctree_lock);
1462
1463		/* Assign foreground process group. */
1464		tp->t_pgrp = p->p_pgrp;
1465		PROC_LOCK(p);
1466		p->p_flag |= P_CONTROLT;
1467		PROC_UNLOCK(p);
1468
1469		return (0);
1470	}
1471	case TIOCSPGRP: {
1472		struct pgrp *pg;
1473
1474		/*
1475		 * XXX: Temporarily unlock the TTY to locate the process
1476		 * group. This code would be lot nicer if we would ever
1477		 * decompose proctree_lock.
1478		 */
1479		tty_unlock(tp);
1480		sx_slock(&proctree_lock);
1481		pg = pgfind(*(int *)data);
1482		if (pg != NULL)
1483			PGRP_UNLOCK(pg);
1484		if (pg == NULL || pg->pg_session != td->td_proc->p_session) {
1485			sx_sunlock(&proctree_lock);
1486			tty_lock(tp);
1487			return (EPERM);
1488		}
1489		tty_lock(tp);
1490
1491		/*
1492		 * Determine if this TTY is the controlling TTY after
1493		 * relocking the TTY.
1494		 */
1495		if (!tty_is_ctty(tp, td->td_proc)) {
1496			sx_sunlock(&proctree_lock);
1497			return (ENOTTY);
1498		}
1499		tp->t_pgrp = pg;
1500		sx_sunlock(&proctree_lock);
1501
1502		/* Wake up the background process groups. */
1503		cv_broadcast(&tp->t_bgwait);
1504		return (0);
1505	}
1506	case TIOCFLUSH: {
1507		int flags = *(int *)data;
1508
1509		if (flags == 0)
1510			flags = (FREAD|FWRITE);
1511		else
1512			flags &= (FREAD|FWRITE);
1513		tty_flush(tp, flags);
1514		return (0);
1515	}
1516	case TIOCDRAIN:
1517		/* Drain TTY output. */
1518		return tty_drain(tp);
1519	case TIOCCONS:
1520		/* Set terminal as console TTY. */
1521		if (*(int *)data) {
1522			error = priv_check(td, PRIV_TTY_CONSOLE);
1523			if (error)
1524				return (error);
1525
1526			/*
1527			 * XXX: constty should really need to be locked!
1528			 * XXX: allow disconnected constty's to be stolen!
1529			 */
1530
1531			if (constty == tp)
1532				return (0);
1533			if (constty != NULL)
1534				return (EBUSY);
1535
1536			tty_unlock(tp);
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		ttydevsw_pktnotify(tp, TIOCPKT_STOP);
1566		return (0);
1567	case TIOCSTART:
1568		tp->t_flags &= ~TF_STOPPED;
1569		ttydevsw_outwakeup(tp);
1570		ttydevsw_pktnotify(tp, TIOCPKT_START);
1571		return (0);
1572	case TIOCSTAT:
1573		tty_info(tp);
1574		return (0);
1575	}
1576
1577#ifdef COMPAT_43TTY
1578	return tty_ioctl_compat(tp, cmd, data, td);
1579#else /* !COMPAT_43TTY */
1580	return (ENOIOCTL);
1581#endif /* COMPAT_43TTY */
1582}
1583
1584int
1585tty_ioctl(struct tty *tp, u_long cmd, void *data, struct thread *td)
1586{
1587	int error;
1588
1589	tty_lock_assert(tp, MA_OWNED);
1590
1591	if (tty_gone(tp))
1592		return (ENXIO);
1593
1594	error = ttydevsw_ioctl(tp, cmd, data, td);
1595	if (error == ENOIOCTL)
1596		error = tty_generic_ioctl(tp, cmd, data, td);
1597
1598	return (error);
1599}
1600
1601dev_t
1602tty_udev(struct tty *tp)
1603{
1604	if (tp->t_dev)
1605		return dev2udev(tp->t_dev);
1606	else
1607		return NODEV;
1608}
1609
1610int
1611tty_checkoutq(struct tty *tp)
1612{
1613
1614	/* 256 bytes should be enough to print a log message. */
1615	return (ttyoutq_bytesleft(&tp->t_outq) >= 256);
1616}
1617
1618void
1619tty_hiwat_in_block(struct tty *tp)
1620{
1621
1622	if ((tp->t_flags & TF_HIWAT_IN) == 0 &&
1623	    tp->t_termios.c_iflag & IXOFF &&
1624	    tp->t_termios.c_cc[VSTOP] != _POSIX_VDISABLE) {
1625		/*
1626		 * Input flow control. Only enter the high watermark when we
1627		 * can successfully store the VSTOP character.
1628		 */
1629		if (ttyoutq_write_nofrag(&tp->t_outq,
1630		    &tp->t_termios.c_cc[VSTOP], 1) == 0)
1631			tp->t_flags |= TF_HIWAT_IN;
1632	} else {
1633		/* No input flow control. */
1634		tp->t_flags |= TF_HIWAT_IN;
1635	}
1636}
1637
1638void
1639tty_hiwat_in_unblock(struct tty *tp)
1640{
1641
1642	if (tp->t_flags & TF_HIWAT_IN &&
1643	    tp->t_termios.c_iflag & IXOFF &&
1644	    tp->t_termios.c_cc[VSTART] != _POSIX_VDISABLE) {
1645		/*
1646		 * Input flow control. Only leave the high watermark when we
1647		 * can successfully store the VSTART character.
1648		 */
1649		if (ttyoutq_write_nofrag(&tp->t_outq,
1650		    &tp->t_termios.c_cc[VSTART], 1) == 0)
1651			tp->t_flags &= ~TF_HIWAT_IN;
1652	} else {
1653		/* No input flow control. */
1654		tp->t_flags &= ~TF_HIWAT_IN;
1655	}
1656
1657	if (!tty_gone(tp))
1658		ttydevsw_inwakeup(tp);
1659}
1660
1661static int
1662ttyhook_defrint(struct tty *tp, char c, int flags)
1663{
1664
1665	if (ttyhook_rint_bypass(tp, &c, 1) != 1)
1666		return (-1);
1667
1668	return (0);
1669}
1670
1671int
1672ttyhook_register(struct tty **rtp, struct thread *td, int fd,
1673    struct ttyhook *th, void *softc)
1674{
1675	struct tty *tp;
1676	struct file *fp;
1677	struct cdev *dev;
1678	struct cdevsw *cdp;
1679	int error;
1680
1681	/* Validate the file descriptor. */
1682	if (fget(td, fd, &fp) != 0)
1683		return (EINVAL);
1684
1685	/* Make sure the vnode is bound to a character device. */
1686	error = EINVAL;
1687	if (fp->f_type != DTYPE_VNODE || fp->f_vnode->v_type != VCHR ||
1688	    fp->f_vnode->v_rdev == NULL)
1689		goto done1;
1690	dev = fp->f_vnode->v_rdev;
1691
1692	/* Make sure it is a TTY. */
1693	cdp = dev_refthread(dev);
1694	if (cdp == NULL)
1695		goto done1;
1696	if (cdp != &ttydev_cdevsw)
1697		goto done2;
1698	tp = dev->si_drv1;
1699
1700	/* Try to attach the hook to the TTY. */
1701	error = EBUSY;
1702	tty_lock(tp);
1703	MPASS((tp->t_hook == NULL) == ((tp->t_flags & TF_HOOK) == 0));
1704	if (tp->t_flags & TF_HOOK)
1705		goto done3;
1706
1707	tp->t_flags |= TF_HOOK;
1708	tp->t_hook = th;
1709	tp->t_hooksoftc = softc;
1710	*rtp = tp;
1711	error = 0;
1712
1713	/* Maybe we can switch into bypass mode now. */
1714	ttydisc_optimize(tp);
1715
1716	/* Silently convert rint() calls to rint_bypass() when possible. */
1717	if (!ttyhook_hashook(tp, rint) && ttyhook_hashook(tp, rint_bypass))
1718		th->th_rint = ttyhook_defrint;
1719
1720done3:	tty_unlock(tp);
1721done2:	dev_relthread(dev);
1722done1:	fdrop(fp, td);
1723	return (error);
1724}
1725
1726void
1727ttyhook_unregister(struct tty *tp)
1728{
1729
1730	tty_lock_assert(tp, MA_OWNED);
1731	MPASS(tp->t_flags & TF_HOOK);
1732
1733	/* Disconnect the hook. */
1734	tp->t_flags &= ~TF_HOOK;
1735	tp->t_hook = NULL;
1736
1737	/* Maybe we need to leave bypass mode. */
1738	ttydisc_optimize(tp);
1739
1740	/* Maybe deallocate the TTY as well. */
1741	tty_rel_free(tp);
1742}
1743
1744#include "opt_ddb.h"
1745#ifdef DDB
1746#include <ddb/ddb.h>
1747#include <ddb/db_sym.h>
1748
1749static struct {
1750	int flag;
1751	char val;
1752} ttystates[] = {
1753#if 0
1754	{ TF_NOPREFIX,	'N' },
1755#endif
1756	{ TF_INITLOCK,	'I' },
1757	{ TF_CALLOUT,	'C' },
1758
1759	/* Keep these together -> 'Oi' and 'Oo'. */
1760	{ TF_OPENED,	'O' },
1761	{ TF_OPENED_IN,	'i' },
1762	{ TF_OPENED_OUT,'o' },
1763
1764	{ TF_GONE,	'G' },
1765	{ TF_OPENCLOSE,	'B' },
1766	{ TF_ASYNC,	'Y' },
1767	{ TF_LITERAL,	'L' },
1768
1769	/* Keep these together -> 'Hi' and 'Ho'. */
1770	{ TF_HIWAT,	'H' },
1771	{ TF_HIWAT_IN,	'i' },
1772	{ TF_HIWAT_OUT,	'o' },
1773
1774	{ TF_STOPPED,	'S' },
1775	{ TF_EXCLUDE,	'X' },
1776	{ TF_BYPASS,	'l' },
1777	{ TF_ZOMBIE,	'Z' },
1778	{ TF_HOOK,	's' },
1779
1780	{ 0,	       '\0' },
1781};
1782
1783#define	TTY_FLAG_BITS \
1784	"\20\1NOPREFIX\2INITLOCK\3CALLOUT\4OPENED_IN\5OPENED_OUT\6GONE" \
1785	"\7OPENCLOSE\10ASYNC\11LITERAL\12HIWAT_IN\13HIWAT_OUT\14STOPPED" \
1786	"\15EXCLUDE\16BYPASS\17ZOMBIE\20HOOK"
1787
1788#define DB_PRINTSYM(name, addr) \
1789	db_printf("%s  " #name ": ", sep); \
1790	db_printsym((db_addr_t) addr, DB_STGY_ANY); \
1791	db_printf("\n");
1792
1793static void
1794_db_show_devsw(const char *sep, const struct ttydevsw *tsw)
1795{
1796	db_printf("%sdevsw: ", sep);
1797	db_printsym((db_addr_t)tsw, DB_STGY_ANY);
1798	db_printf(" (%p)\n", tsw);
1799	DB_PRINTSYM(open, tsw->tsw_open);
1800	DB_PRINTSYM(close, tsw->tsw_close);
1801	DB_PRINTSYM(outwakeup, tsw->tsw_outwakeup);
1802	DB_PRINTSYM(inwakeup, tsw->tsw_inwakeup);
1803	DB_PRINTSYM(ioctl, tsw->tsw_ioctl);
1804	DB_PRINTSYM(param, tsw->tsw_param);
1805	DB_PRINTSYM(modem, tsw->tsw_modem);
1806	DB_PRINTSYM(mmap, tsw->tsw_mmap);
1807	DB_PRINTSYM(pktnotify, tsw->tsw_pktnotify);
1808	DB_PRINTSYM(free, tsw->tsw_free);
1809}
1810static void
1811_db_show_hooks(const char *sep, const struct ttyhook *th)
1812{
1813	db_printf("%shook: ", sep);
1814	db_printsym((db_addr_t)th, DB_STGY_ANY);
1815	db_printf(" (%p)\n", th);
1816	if (th == NULL)
1817		return;
1818	DB_PRINTSYM(rint, th->th_rint);
1819	DB_PRINTSYM(rint_bypass, th->th_rint_bypass);
1820	DB_PRINTSYM(rint_done, th->th_rint_done);
1821	DB_PRINTSYM(rint_poll, th->th_rint_poll);
1822	DB_PRINTSYM(getc_inject, th->th_getc_inject);
1823	DB_PRINTSYM(getc_capture, th->th_getc_capture);
1824	DB_PRINTSYM(getc_poll, th->th_getc_poll);
1825	DB_PRINTSYM(close, th->th_close);
1826}
1827
1828static void
1829_db_show_termios(const char *name, const struct termios *t)
1830{
1831
1832	db_printf("%s: iflag 0x%x oflag 0x%x cflag 0x%x "
1833	    "lflag 0x%x ispeed %u ospeed %u\n", name,
1834	    t->c_iflag, t->c_oflag, t->c_cflag, t->c_lflag,
1835	    t->c_ispeed, t->c_ospeed);
1836}
1837
1838/* DDB command to show TTY statistics. */
1839DB_SHOW_COMMAND(tty, db_show_tty)
1840{
1841	struct tty *tp;
1842
1843	if (!have_addr) {
1844		db_printf("usage: show tty <addr>\n");
1845		return;
1846	}
1847	tp = (struct tty *)addr;
1848
1849	db_printf("0x%p: %s\n", tp, tty_devname(tp));
1850	db_printf("\tmtx: %p\n", tp->t_mtx);
1851	db_printf("\tflags: %b\n", tp->t_flags, TTY_FLAG_BITS);
1852	db_printf("\trevokecnt: %u\n", tp->t_revokecnt);
1853
1854	/* Buffering mechanisms. */
1855	db_printf("\tinq: %p begin %u linestart %u reprint %u end %u "
1856	    "nblocks %u quota %u\n", &tp->t_inq, tp->t_inq.ti_begin,
1857	    tp->t_inq.ti_linestart, tp->t_inq.ti_reprint, tp->t_inq.ti_end,
1858	    tp->t_inq.ti_nblocks, tp->t_inq.ti_quota);
1859	db_printf("\toutq: %p begin %u end %u nblocks %u quota %u\n",
1860	    &tp->t_outq, tp->t_outq.to_begin, tp->t_outq.to_end,
1861	    tp->t_outq.to_nblocks, tp->t_outq.to_quota);
1862	db_printf("\tinlow: %zu\n", tp->t_inlow);
1863	db_printf("\toutlow: %zu\n", tp->t_outlow);
1864	_db_show_termios("\ttermios", &tp->t_termios);
1865	db_printf("\twinsize: row %u col %u xpixel %u ypixel %u\n",
1866	    tp->t_winsize.ws_row, tp->t_winsize.ws_col,
1867	    tp->t_winsize.ws_xpixel, tp->t_winsize.ws_ypixel);
1868	db_printf("\tcolumn: %u\n", tp->t_column);
1869	db_printf("\twritepos: %u\n", tp->t_writepos);
1870	db_printf("\tcompatflags: 0x%x\n", tp->t_compatflags);
1871
1872	/* Init/lock-state devices. */
1873	_db_show_termios("\ttermios_init_in", &tp->t_termios_init_in);
1874	_db_show_termios("\ttermios_init_out", &tp->t_termios_init_out);
1875	_db_show_termios("\ttermios_lock_in", &tp->t_termios_lock_in);
1876	_db_show_termios("\ttermios_lock_out", &tp->t_termios_lock_out);
1877
1878	/* Hooks */
1879	_db_show_devsw("\t", tp->t_devsw);
1880	_db_show_hooks("\t", tp->t_hook);
1881
1882	/* Process info. */
1883	db_printf("\tpgrp: %p gid %d jobc %d\n", tp->t_pgrp,
1884	    tp->t_pgrp ? tp->t_pgrp->pg_id : 0,
1885	    tp->t_pgrp ? tp->t_pgrp->pg_jobc : 0);
1886	db_printf("\tsession: %p", tp->t_session);
1887	if (tp->t_session != NULL)
1888	    db_printf(" count %u leader %p tty %p sid %d login %s",
1889		tp->t_session->s_count, tp->t_session->s_leader,
1890		tp->t_session->s_ttyp, tp->t_session->s_sid,
1891		tp->t_session->s_login);
1892	db_printf("\n");
1893	db_printf("\tsessioncnt: %u\n", tp->t_sessioncnt);
1894	db_printf("\tdevswsoftc: %p\n", tp->t_devswsoftc);
1895	db_printf("\thooksoftc: %p\n", tp->t_hooksoftc);
1896	db_printf("\tdev: %p\n", tp->t_dev);
1897}
1898
1899/* DDB command to list TTYs. */
1900DB_SHOW_ALL_COMMAND(ttys, db_show_all_ttys)
1901{
1902	struct tty *tp;
1903	size_t isiz, osiz;
1904	int i, j;
1905
1906	/* Make the output look like `pstat -t'. */
1907	db_printf("PTR        ");
1908#if defined(__LP64__)
1909	db_printf("        ");
1910#endif
1911	db_printf("      LINE   INQ  CAN  LIN  LOW  OUTQ  USE  LOW   "
1912	    "COL  SESS  PGID STATE\n");
1913
1914	TAILQ_FOREACH(tp, &tty_list, t_list) {
1915		isiz = tp->t_inq.ti_nblocks * TTYINQ_DATASIZE;
1916		osiz = tp->t_outq.to_nblocks * TTYOUTQ_DATASIZE;
1917
1918		db_printf("%p %10s %5zu %4u %4u %4zu %5zu %4u %4zu %5u %5d %5d ",
1919		    tp,
1920		    tty_devname(tp),
1921		    isiz,
1922		    tp->t_inq.ti_linestart - tp->t_inq.ti_begin,
1923		    tp->t_inq.ti_end - tp->t_inq.ti_linestart,
1924		    isiz - tp->t_inlow,
1925		    osiz,
1926		    tp->t_outq.to_end - tp->t_outq.to_begin,
1927		    osiz - tp->t_outlow,
1928		    tp->t_column,
1929		    tp->t_session ? tp->t_session->s_sid : 0,
1930		    tp->t_pgrp ? tp->t_pgrp->pg_id : 0);
1931
1932		/* Flag bits. */
1933		for (i = j = 0; ttystates[i].flag; i++)
1934			if (tp->t_flags & ttystates[i].flag) {
1935				db_printf("%c", ttystates[i].val);
1936				j++;
1937			}
1938		if (j == 0)
1939			db_printf("-");
1940		db_printf("\n");
1941	}
1942}
1943#endif /* DDB */
1944