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