xref: /f-stack/freebsd/sys/tty.h (revision 22ce4aff)
1a9643ea8Slogwang /*-
2*22ce4affSfengbojiang  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3*22ce4affSfengbojiang  *
4a9643ea8Slogwang  * Copyright (c) 2008 Ed Schouten <[email protected]>
5a9643ea8Slogwang  * All rights reserved.
6a9643ea8Slogwang  *
7a9643ea8Slogwang  * Portions of this software were developed under sponsorship from Snow
8a9643ea8Slogwang  * B.V., the Netherlands.
9a9643ea8Slogwang  *
10a9643ea8Slogwang  * Redistribution and use in source and binary forms, with or without
11a9643ea8Slogwang  * modification, are permitted provided that the following conditions
12a9643ea8Slogwang  * are met:
13a9643ea8Slogwang  * 1. Redistributions of source code must retain the above copyright
14a9643ea8Slogwang  *    notice, this list of conditions and the following disclaimer.
15a9643ea8Slogwang  * 2. Redistributions in binary form must reproduce the above copyright
16a9643ea8Slogwang  *    notice, this list of conditions and the following disclaimer in the
17a9643ea8Slogwang  *    documentation and/or other materials provided with the distribution.
18a9643ea8Slogwang  *
19a9643ea8Slogwang  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20a9643ea8Slogwang  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21a9643ea8Slogwang  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22a9643ea8Slogwang  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23a9643ea8Slogwang  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24a9643ea8Slogwang  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25a9643ea8Slogwang  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26a9643ea8Slogwang  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27a9643ea8Slogwang  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28a9643ea8Slogwang  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29a9643ea8Slogwang  * SUCH DAMAGE.
30a9643ea8Slogwang  *
31a9643ea8Slogwang  * $FreeBSD$
32a9643ea8Slogwang  */
33a9643ea8Slogwang 
34a9643ea8Slogwang #ifndef _SYS_TTY_H_
35a9643ea8Slogwang #define	_SYS_TTY_H_
36a9643ea8Slogwang 
37a9643ea8Slogwang #include <sys/param.h>
38a9643ea8Slogwang #include <sys/queue.h>
39a9643ea8Slogwang #include <sys/lock.h>
40a9643ea8Slogwang #include <sys/mutex.h>
41a9643ea8Slogwang #include <sys/condvar.h>
42a9643ea8Slogwang #include <sys/selinfo.h>
43a9643ea8Slogwang #include <sys/_termios.h>
44a9643ea8Slogwang #include <sys/ttycom.h>
45a9643ea8Slogwang #include <sys/ttyqueue.h>
46a9643ea8Slogwang 
47a9643ea8Slogwang struct cdev;
48a9643ea8Slogwang struct file;
49a9643ea8Slogwang struct pgrp;
50a9643ea8Slogwang struct session;
51a9643ea8Slogwang struct ucred;
52a9643ea8Slogwang 
53a9643ea8Slogwang struct ttydevsw;
54a9643ea8Slogwang 
55a9643ea8Slogwang /*
56a9643ea8Slogwang  * Per-TTY structure, containing buffers, etc.
57a9643ea8Slogwang  *
58a9643ea8Slogwang  * List of locks
59a9643ea8Slogwang  * (t)	locked by t_mtx
60a9643ea8Slogwang  * (l)	locked by tty_list_sx
61a9643ea8Slogwang  * (c)	const until freeing
62a9643ea8Slogwang  */
63a9643ea8Slogwang struct tty {
64a9643ea8Slogwang 	struct mtx	*t_mtx;		/* TTY lock. */
65a9643ea8Slogwang 	struct mtx	t_mtxobj;	/* Per-TTY lock (when not borrowing). */
66a9643ea8Slogwang 	TAILQ_ENTRY(tty) t_list;	/* (l) TTY list entry. */
67*22ce4affSfengbojiang 	int		t_drainwait;	/* (t) TIOCDRAIN timeout seconds. */
68a9643ea8Slogwang 	unsigned int	t_flags;	/* (t) Terminal option flags. */
69a9643ea8Slogwang /* Keep flags in sync with db_show_tty and pstat(8). */
70a9643ea8Slogwang #define	TF_NOPREFIX	0x00001	/* Don't prepend "tty" to device name. */
71a9643ea8Slogwang #define	TF_INITLOCK	0x00002	/* Create init/lock state devices. */
72a9643ea8Slogwang #define	TF_CALLOUT	0x00004	/* Create "cua" devices. */
73a9643ea8Slogwang #define	TF_OPENED_IN	0x00008	/* "tty" node is in use. */
74a9643ea8Slogwang #define	TF_OPENED_OUT	0x00010	/* "cua" node is in use. */
75a9643ea8Slogwang #define	TF_OPENED_CONS	0x00020 /* Device in use as console. */
76a9643ea8Slogwang #define	TF_OPENED	(TF_OPENED_IN|TF_OPENED_OUT|TF_OPENED_CONS)
77a9643ea8Slogwang #define	TF_GONE		0x00040	/* Device node is gone. */
78a9643ea8Slogwang #define	TF_OPENCLOSE	0x00080	/* Device is in open()/close(). */
79a9643ea8Slogwang #define	TF_ASYNC	0x00100	/* Asynchronous I/O enabled. */
80a9643ea8Slogwang #define	TF_LITERAL	0x00200	/* Accept the next character literally. */
81a9643ea8Slogwang #define	TF_HIWAT_IN	0x00400	/* We've reached the input watermark. */
82a9643ea8Slogwang #define	TF_HIWAT_OUT	0x00800	/* We've reached the output watermark. */
83a9643ea8Slogwang #define	TF_HIWAT	(TF_HIWAT_IN|TF_HIWAT_OUT)
84a9643ea8Slogwang #define	TF_STOPPED	0x01000	/* Output flow control - stopped. */
85a9643ea8Slogwang #define	TF_EXCLUDE	0x02000	/* Exclusive access. */
86a9643ea8Slogwang #define	TF_BYPASS	0x04000	/* Optimized input path. */
87a9643ea8Slogwang #define	TF_ZOMBIE	0x08000	/* Modem disconnect received. */
88a9643ea8Slogwang #define	TF_HOOK		0x10000	/* TTY has hook attached. */
89a9643ea8Slogwang #define	TF_BUSY_IN	0x20000	/* Process busy in read() -- not supported. */
90a9643ea8Slogwang #define	TF_BUSY_OUT	0x40000	/* Process busy in write(). */
91a9643ea8Slogwang #define	TF_BUSY		(TF_BUSY_IN|TF_BUSY_OUT)
92a9643ea8Slogwang 	unsigned int	t_revokecnt;	/* (t) revoke() count. */
93a9643ea8Slogwang 
94a9643ea8Slogwang 	/* Buffering mechanisms. */
95a9643ea8Slogwang 	struct ttyinq	t_inq;		/* (t) Input queue. */
96a9643ea8Slogwang 	size_t		t_inlow;	/* (t) Input low watermark. */
97a9643ea8Slogwang 	struct ttyoutq	t_outq;		/* (t) Output queue. */
98a9643ea8Slogwang 	size_t		t_outlow;	/* (t) Output low watermark. */
99a9643ea8Slogwang 
100a9643ea8Slogwang 	/* Sleeping mechanisms. */
101a9643ea8Slogwang 	struct cv	t_inwait;	/* (t) Input wait queue. */
102a9643ea8Slogwang 	struct cv	t_outwait;	/* (t) Output wait queue. */
103a9643ea8Slogwang 	struct cv	t_outserwait;	/* (t) Serial output wait queue. */
104a9643ea8Slogwang 	struct cv	t_bgwait;	/* (t) Background wait queue. */
105a9643ea8Slogwang 	struct cv	t_dcdwait;	/* (t) Carrier Detect wait queue. */
106a9643ea8Slogwang 
107a9643ea8Slogwang 	/* Polling mechanisms. */
108a9643ea8Slogwang 	struct selinfo	t_inpoll;	/* (t) Input poll queue. */
109a9643ea8Slogwang 	struct selinfo	t_outpoll;	/* (t) Output poll queue. */
110a9643ea8Slogwang 	struct sigio	*t_sigio;	/* (t) Asynchronous I/O. */
111a9643ea8Slogwang 
112a9643ea8Slogwang 	struct termios	t_termios;	/* (t) I/O processing flags. */
113a9643ea8Slogwang 	struct winsize	t_winsize;	/* (t) Window size. */
114a9643ea8Slogwang 	unsigned int	t_column;	/* (t) Current cursor position. */
115a9643ea8Slogwang 	unsigned int	t_writepos;	/* (t) Where input was interrupted. */
116a9643ea8Slogwang 	int		t_compatflags;	/* (t) COMPAT_43TTY flags. */
117a9643ea8Slogwang 
118a9643ea8Slogwang 	/* Init/lock-state devices. */
119a9643ea8Slogwang 	struct termios	t_termios_init_in;	/* tty%s.init. */
120a9643ea8Slogwang 	struct termios	t_termios_lock_in;	/* tty%s.lock. */
121a9643ea8Slogwang 	struct termios	t_termios_init_out;	/* cua%s.init. */
122a9643ea8Slogwang 	struct termios	t_termios_lock_out;	/* cua%s.lock. */
123a9643ea8Slogwang 
124a9643ea8Slogwang 	struct ttydevsw	*t_devsw;	/* (c) Driver hooks. */
125a9643ea8Slogwang 	struct ttyhook	*t_hook;	/* (t) Capture/inject hook. */
126a9643ea8Slogwang 
127a9643ea8Slogwang 	/* Process signal delivery. */
128a9643ea8Slogwang 	struct pgrp	*t_pgrp;	/* (t) Foreground process group. */
129a9643ea8Slogwang 	struct session	*t_session;	/* (t) Associated session. */
130a9643ea8Slogwang 	unsigned int	t_sessioncnt;	/* (t) Backpointing sessions. */
131a9643ea8Slogwang 
132a9643ea8Slogwang 	void		*t_devswsoftc;	/* (c) Soft config, for drivers. */
133a9643ea8Slogwang 	void		*t_hooksoftc;	/* (t) Soft config, for hooks. */
134a9643ea8Slogwang 	struct cdev	*t_dev;		/* (c) Primary character device. */
135*22ce4affSfengbojiang 
136*22ce4affSfengbojiang 	size_t		t_prbufsz;	/* (t) SIGINFO buffer size. */
137*22ce4affSfengbojiang 	char		t_prbuf[];	/* (t) SIGINFO buffer. */
138a9643ea8Slogwang };
139a9643ea8Slogwang 
140a9643ea8Slogwang /*
141a9643ea8Slogwang  * Userland version of struct tty, for sysctl kern.ttys
142a9643ea8Slogwang  */
143a9643ea8Slogwang struct xtty {
144a9643ea8Slogwang 	size_t	xt_size;	/* Structure size. */
145a9643ea8Slogwang 	size_t	xt_insize;	/* Input queue size. */
146a9643ea8Slogwang 	size_t	xt_incc;	/* Canonicalized characters. */
147a9643ea8Slogwang 	size_t	xt_inlc;	/* Input line charaters. */
148a9643ea8Slogwang 	size_t	xt_inlow;	/* Input low watermark. */
149a9643ea8Slogwang 	size_t	xt_outsize;	/* Output queue size. */
150a9643ea8Slogwang 	size_t	xt_outcc;	/* Output queue usage. */
151a9643ea8Slogwang 	size_t	xt_outlow;	/* Output low watermark. */
152a9643ea8Slogwang 	unsigned int xt_column;	/* Current column position. */
153a9643ea8Slogwang 	pid_t	xt_pgid;	/* Foreground process group. */
154a9643ea8Slogwang 	pid_t	xt_sid;		/* Session. */
155a9643ea8Slogwang 	unsigned int xt_flags;	/* Terminal option flags. */
156*22ce4affSfengbojiang 	uint32_t xt_dev;	/* Userland device. XXXKIB truncated */
157a9643ea8Slogwang };
158a9643ea8Slogwang 
159a9643ea8Slogwang #ifdef _KERNEL
160a9643ea8Slogwang 
161a9643ea8Slogwang /* Used to distinguish between normal, callout, lock and init devices. */
162a9643ea8Slogwang #define	TTYUNIT_INIT		0x1
163a9643ea8Slogwang #define	TTYUNIT_LOCK		0x2
164a9643ea8Slogwang #define	TTYUNIT_CALLOUT		0x4
165a9643ea8Slogwang 
166a9643ea8Slogwang /* Allocation and deallocation. */
167a9643ea8Slogwang struct tty *tty_alloc(struct ttydevsw *tsw, void *softc);
168a9643ea8Slogwang struct tty *tty_alloc_mutex(struct ttydevsw *tsw, void *softc, struct mtx *mtx);
169a9643ea8Slogwang void	tty_rel_pgrp(struct tty *tp, struct pgrp *pgrp);
170a9643ea8Slogwang void	tty_rel_sess(struct tty *tp, struct session *sess);
171a9643ea8Slogwang void	tty_rel_gone(struct tty *tp);
172a9643ea8Slogwang 
173a9643ea8Slogwang #define	tty_lock(tp)		mtx_lock((tp)->t_mtx)
174a9643ea8Slogwang #define	tty_unlock(tp)		mtx_unlock((tp)->t_mtx)
175a9643ea8Slogwang #define	tty_lock_owned(tp)	mtx_owned((tp)->t_mtx)
176*22ce4affSfengbojiang #define	tty_assert_locked(tp)	mtx_assert((tp)->t_mtx, MA_OWNED)
177a9643ea8Slogwang #define	tty_getlock(tp)		((tp)->t_mtx)
178a9643ea8Slogwang 
179*22ce4affSfengbojiang /* XXX Should migrate users to tty_assert_locked! */
180*22ce4affSfengbojiang #define	tty_lock_assert(tp, ma)	mtx_assert((tp)->t_mtx, (ma))
181*22ce4affSfengbojiang 
182a9643ea8Slogwang /* Device node creation. */
183a9643ea8Slogwang int	tty_makedevf(struct tty *tp, struct ucred *cred, int flags,
184a9643ea8Slogwang     const char *fmt, ...) __printflike(4, 5);
185a9643ea8Slogwang #define	TTYMK_CLONING		0x1
186a9643ea8Slogwang #define	tty_makedev(tp, cred, fmt, ...) \
187a9643ea8Slogwang 	(void )tty_makedevf((tp), (cred), 0, (fmt), ## __VA_ARGS__)
188a9643ea8Slogwang #define	tty_makealias(tp,fmt,...) \
189a9643ea8Slogwang 	make_dev_alias((tp)->t_dev, fmt, ## __VA_ARGS__)
190a9643ea8Slogwang 
191a9643ea8Slogwang /* Signalling processes. */
192a9643ea8Slogwang void	tty_signal_sessleader(struct tty *tp, int signal);
193a9643ea8Slogwang void	tty_signal_pgrp(struct tty *tp, int signal);
194a9643ea8Slogwang /* Waking up readers/writers. */
195a9643ea8Slogwang int	tty_wait(struct tty *tp, struct cv *cv);
196a9643ea8Slogwang int	tty_wait_background(struct tty *tp, struct thread *td, int sig);
197a9643ea8Slogwang int	tty_timedwait(struct tty *tp, struct cv *cv, int timo);
198a9643ea8Slogwang void	tty_wakeup(struct tty *tp, int flags);
199a9643ea8Slogwang 
200a9643ea8Slogwang /* System messages. */
201a9643ea8Slogwang int	tty_checkoutq(struct tty *tp);
202a9643ea8Slogwang int	tty_putchar(struct tty *tp, char c);
203*22ce4affSfengbojiang int	tty_putstrn(struct tty *tp, const char *p, size_t n);
204a9643ea8Slogwang 
205a9643ea8Slogwang int	tty_ioctl(struct tty *tp, u_long cmd, void *data, int fflag,
206a9643ea8Slogwang     struct thread *td);
207a9643ea8Slogwang int	tty_ioctl_compat(struct tty *tp, u_long cmd, caddr_t data,
208a9643ea8Slogwang     int fflag, struct thread *td);
209a9643ea8Slogwang void	tty_set_winsize(struct tty *tp, const struct winsize *wsz);
210a9643ea8Slogwang void	tty_init_console(struct tty *tp, speed_t speed);
211a9643ea8Slogwang void	tty_flush(struct tty *tp, int flags);
212a9643ea8Slogwang void	tty_hiwat_in_block(struct tty *tp);
213a9643ea8Slogwang void	tty_hiwat_in_unblock(struct tty *tp);
214a9643ea8Slogwang dev_t	tty_udev(struct tty *tp);
215a9643ea8Slogwang #define	tty_opened(tp)		((tp)->t_flags & TF_OPENED)
216a9643ea8Slogwang #define	tty_gone(tp)		((tp)->t_flags & TF_GONE)
217a9643ea8Slogwang #define	tty_softc(tp)		((tp)->t_devswsoftc)
218a9643ea8Slogwang #define	tty_devname(tp)		devtoname((tp)->t_dev)
219a9643ea8Slogwang 
220a9643ea8Slogwang /* Status line printing. */
221a9643ea8Slogwang void	tty_info(struct tty *tp);
222a9643ea8Slogwang 
223a9643ea8Slogwang /* /dev/console selection. */
224a9643ea8Slogwang void	ttyconsdev_select(const char *name);
225a9643ea8Slogwang 
226a9643ea8Slogwang /* Pseudo-terminal hooks. */
227a9643ea8Slogwang int	pts_alloc(int fflags, struct thread *td, struct file *fp);
228a9643ea8Slogwang int	pts_alloc_external(int fd, struct thread *td, struct file *fp,
229a9643ea8Slogwang     struct cdev *dev, const char *name);
230a9643ea8Slogwang 
231a9643ea8Slogwang /* Drivers and line disciplines also need to call these. */
232a9643ea8Slogwang #include <sys/ttydisc.h>
233a9643ea8Slogwang #include <sys/ttydevsw.h>
234a9643ea8Slogwang #include <sys/ttyhook.h>
235a9643ea8Slogwang #endif /* _KERNEL */
236a9643ea8Slogwang 
237a9643ea8Slogwang #endif /* !_SYS_TTY_H_ */
238