11539Srgrimes/*-
293747Smike * Copyright (c) 2008 Ed Schouten <ed@FreeBSD.org>
393747Smike * All rights reserved.
41539Srgrimes *
51539Srgrimes * Redistribution and use in source and binary forms, with or without
61539Srgrimes * modification, are permitted provided that the following conditions
71539Srgrimes * are met:
81539Srgrimes * 1. Redistributions of source code must retain the above copyright
91539Srgrimes *    notice, this list of conditions and the following disclaimer.
101539Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111539Srgrimes *    notice, this list of conditions and the following disclaimer in the
121539Srgrimes *    documentation and/or other materials provided with the distribution.
131539Srgrimes *
1493747Smike * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
151539Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
161539Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1793747Smike * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
181539Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
191539Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
201539Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
211539Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
221539Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
231539Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
241539Srgrimes * SUCH DAMAGE.
251539Srgrimes *
2693747Smike * $FreeBSD$
271539Srgrimes */
281539Srgrimes
2993747Smike#ifndef _SYS_TTYHOOK_H_
3093747Smike#define	_SYS_TTYHOOK_H_
3193747Smike
3293747Smike#ifndef _SYS_TTY_H_
33102227Smike#error "can only be included through <sys/tty.h>"
3493747Smike#endif /* !_SYS_TTY_H_ */
35102227Smike
36102227Smikestruct tty;
37102227Smike
3893747Smike/*
3993747Smike * Hooks interface, which allows to capture and inject traffic into the
4093747Smike * input and output paths of a TTY.
41189350Sdas */
42132577Stjr
43132577Stjrtypedef int th_rint_t(struct tty *tp, char c, int flags);
44132577Stjrtypedef size_t th_rint_bypass_t(struct tty *tp, const void *buf, size_t len);
45189350Sdastypedef void th_rint_done_t(struct tty *tp);
46189350Sdastypedef size_t th_rint_poll_t(struct tty *tp);
47132577Stjr
48189350Sdastypedef size_t th_getc_inject_t(struct tty *tp, void *buf, size_t len);
49131875Sdestypedef void th_getc_capture_t(struct tty *tp, const void *buf, size_t len);
50132577Stjrtypedef size_t th_getc_poll_t(struct tty *tp);
51184587Skib
52132577Stjrtypedef void th_close_t(struct tty *tp);
53132577Stjr
54184587Skibstruct ttyhook {
55131875Sdes	/* Character input. */
56189350Sdas	th_rint_t		*th_rint;
57132577Stjr	th_rint_bypass_t	*th_rint_bypass;
58132577Stjr	th_rint_done_t		*th_rint_done;
59189350Sdas	th_rint_poll_t		*th_rint_poll;
60132577Stjr
61132577Stjr	/* Character output. */
6293747Smike	th_getc_inject_t	*th_getc_inject;
6393747Smike	th_getc_capture_t	*th_getc_capture;
6493747Smike	th_getc_poll_t		*th_getc_poll;
65
66	th_close_t		*th_close;
67};
68
69int	ttyhook_register(struct tty **, struct proc *, int,
70    struct ttyhook *, void *);
71void	ttyhook_unregister(struct tty *);
72#define	ttyhook_softc(tp)		((tp)->t_hooksoftc)
73#define	ttyhook_hashook(tp,hook)	((tp)->t_hook != NULL && \
74					(tp)->t_hook->th_ ## hook != NULL)
75
76static __inline int
77ttyhook_rint(struct tty *tp, char c, int flags)
78{
79	tty_lock_assert(tp, MA_OWNED);
80	MPASS(!tty_gone(tp));
81
82	return tp->t_hook->th_rint(tp, c, flags);
83}
84
85static __inline size_t
86ttyhook_rint_bypass(struct tty *tp, const void *buf, size_t len)
87{
88	tty_lock_assert(tp, MA_OWNED);
89	MPASS(!tty_gone(tp));
90
91	return tp->t_hook->th_rint_bypass(tp, buf, len);
92}
93
94static __inline void
95ttyhook_rint_done(struct tty *tp)
96{
97	tty_lock_assert(tp, MA_OWNED);
98	MPASS(!tty_gone(tp));
99
100	tp->t_hook->th_rint_done(tp);
101}
102
103static __inline size_t
104ttyhook_rint_poll(struct tty *tp)
105{
106	tty_lock_assert(tp, MA_OWNED);
107	MPASS(!tty_gone(tp));
108
109	return tp->t_hook->th_rint_poll(tp);
110}
111
112static __inline size_t
113ttyhook_getc_inject(struct tty *tp, void *buf, size_t len)
114{
115	tty_lock_assert(tp, MA_OWNED);
116	MPASS(!tty_gone(tp));
117
118	return tp->t_hook->th_getc_inject(tp, buf, len);
119}
120
121static __inline void
122ttyhook_getc_capture(struct tty *tp, const void *buf, size_t len)
123{
124	tty_lock_assert(tp, MA_OWNED);
125	MPASS(!tty_gone(tp));
126
127	tp->t_hook->th_getc_capture(tp, buf, len);
128}
129
130static __inline size_t
131ttyhook_getc_poll(struct tty *tp)
132{
133	tty_lock_assert(tp, MA_OWNED);
134	MPASS(!tty_gone(tp));
135
136	return tp->t_hook->th_getc_poll(tp);
137}
138
139static __inline void
140ttyhook_close(struct tty *tp)
141{
142	tty_lock_assert(tp, MA_OWNED);
143
144	tp->t_hook->th_close(tp);
145}
146
147#endif /* !_SYS_TTYHOOK_H_ */
148