Date: Thu, 21 Aug 2008 17:21:34 GMT From: Ed Schouten <ed@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 148015 for review Message-ID: <200808211721.m7LHLY8m069277@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=148015 Change 148015 by ed@ed_dull on 2008/08/21 17:21:29 Already add some really premature (prototype) ttyhook bits. ttyhook will be a new programming interface to capture/inject data into TTY's, which can be used by ppp(4), sl(4), snp(4), ng_h4(4) and ng_tty(4). Affected files ... .. //depot/projects/mpsafetty/sys/dev/snp/snp.c#3 edit .. //depot/projects/mpsafetty/sys/kern/tty.c#24 edit .. //depot/projects/mpsafetty/sys/modules/snp/Makefile#2 edit .. //depot/projects/mpsafetty/sys/sys/tty.h#14 edit .. //depot/projects/mpsafetty/sys/sys/ttyhook.h#1 add Differences ... ==== //depot/projects/mpsafetty/sys/dev/snp/snp.c#3 (text+ko) ==== @@ -1,608 +1,135 @@ /*- - * Copyright (c) 1995 Ugen J.S.Antsilevich + * Copyright (c) 2008 Ed Schouten <ed@FreeBSD.org> + * All rights reserved. * - * Redistribution and use in source forms, with and without modification, - * are permitted provided that this entire comment appears intact. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * Redistribution in binary form may occur without any restrictions. - * Obviously, it would be nice if you gave credit where credit is due - * but requiring it would be too onerous. - * - * This software is provided ``AS IS'' without any warranties of any kind. - * - * Snoop stuff. - * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sys/dev/snp/snp.c,v 1.109 2008/08/15 13:07:07 ed Exp $"); +__FBSDID("$FreeBSD$"); #include <sys/param.h> -#include <sys/systm.h> -#include <sys/fcntl.h> -#include <sys/filio.h> -#include <sys/malloc.h> -#include <sys/tty.h> #include <sys/conf.h> -#include <sys/poll.h> #include <sys/kernel.h> +#include <sys/malloc.h> #include <sys/module.h> -#include <sys/queue.h> #include <sys/snoop.h> -#include <sys/uio.h> -#include <sys/file.h> -#include <sys/vnode.h> +#include <sys/systm.h> +#include <sys/tty.h> + +static struct cdev *snp_dev; +static struct mtx snp_register_mtx; +MTX_SYSINIT(snp_register_mtx, &snp_register_mtx, + "tty snoop registration", MTX_DEF); +static MALLOC_DEFINE(M_SNP, "snp", "tty snoop device"); -static l_close_t snplclose; -static l_write_t snplwrite; -static d_open_t snpopen; -static d_read_t snpread; -static d_write_t snpwrite; -static d_ioctl_t snpioctl; -static d_poll_t snppoll; +static d_open_t snp_open; +static d_read_t snp_read; +static d_write_t snp_write; +static d_ioctl_t snp_ioctl; static struct cdevsw snp_cdevsw = { .d_version = D_VERSION, - .d_flags = D_PSEUDO | D_NEEDGIANT | D_NEEDMINOR, - .d_open = snpopen, - .d_read = snpread, - .d_write = snpwrite, - .d_ioctl = snpioctl, - .d_poll = snppoll, + .d_open = snp_open, + .d_read = snp_read, + .d_write = snp_write, + .d_ioctl = snp_ioctl, .d_name = "snp", }; -static struct linesw snpdisc = { - .l_open = tty_open, - .l_close = snplclose, - .l_read = ttread, - .l_write = snplwrite, - .l_ioctl = l_nullioctl, - .l_rint = ttyinput, - .l_start = ttstart, - .l_modem = ttymodem -}; +static struct ttyhook snp_hook; /* XXX */ -/* - * This is the main snoop per-device structure. - */ -struct snoop { - LIST_ENTRY(snoop) snp_list; /* List glue. */ - struct cdev *snp_target; /* Target tty device. */ - struct tty *snp_tty; /* Target tty pointer. */ - u_long snp_len; /* Possible length. */ - u_long snp_base; /* Data base. */ - u_long snp_blen; /* Used length. */ - caddr_t snp_buf; /* Allocation pointer. */ - int snp_flags; /* Flags. */ - struct selinfo snp_sel; /* Select info. */ - int snp_olddisc; /* Old line discipline. */ +struct snp_softc { + struct tty *snp_tty; + /* XXX */ }; -/* - * Possible flags. - */ -#define SNOOP_ASYNC 0x0002 -#define SNOOP_OPEN 0x0004 -#define SNOOP_RWAIT 0x0008 -#define SNOOP_OFLOW 0x0010 -#define SNOOP_DOWN 0x0020 - -/* - * Other constants. - */ -#define SNOOP_MINLEN (4*1024) /* This should be power of 2. - * 4K tested to be the minimum - * for which on normal tty - * usage there is no need to - * allocate more. - */ -#define SNOOP_MAXLEN (64*1024) /* This one also,64K enough - * If we grow more,something - * really bad in this world.. - */ - -static MALLOC_DEFINE(M_SNP, "snp", "Snoop device data"); -/* - * The number of the "snoop" line discipline. This gets determined at - * module load time. - */ -static int snooplinedisc; -static struct cdev *snoopdev; - -static LIST_HEAD(, snoop) snp_sclist = LIST_HEAD_INITIALIZER(&snp_sclist); - -static struct tty *snpdevtotty(struct cdev *dev); -static void snp_detach(void *arg); -static int snp_down(struct snoop *snp); -static int snp_in(struct snoop *snp, char *buf, int n); -static int snp_modevent(module_t mod, int what, void *arg); -static struct snoop *ttytosnp(struct tty *); - -static struct snoop * -ttytosnp(struct tty *tp) -{ - struct snoop *snp; - - LIST_FOREACH(snp, &snp_sclist, snp_list) { - if (snp->snp_tty == tp) - return (snp); - } - return (NULL); -} - -static int -snplclose(struct tty *tp, int flag) -{ - struct snoop *snp; - int error; - - snp = ttytosnp(tp); - error = snp_down(snp); - if (error != 0) - return (error); - error = ttylclose(tp, flag); - return (error); -} - -static int -snplwrite(struct tty *tp, struct uio *uio, int flag) -{ - struct iovec iov; - struct uio uio2; - struct snoop *snp; - int error, ilen; - char *ibuf; - - error = 0; - ibuf = NULL; - snp = ttytosnp(tp); - while (uio->uio_resid > 0) { - ilen = imin(512, uio->uio_resid); - ibuf = malloc(ilen, M_SNP, M_WAITOK); - error = uiomove(ibuf, ilen, uio); - if (error != 0) - break; - snp_in(snp, ibuf, ilen); - /* Hackish, but probably the least of all evils. */ - iov.iov_base = ibuf; - iov.iov_len = ilen; - uio2.uio_iov = &iov; - uio2.uio_iovcnt = 1; - uio2.uio_offset = 0; - uio2.uio_resid = ilen; - uio2.uio_segflg = UIO_SYSSPACE; - uio2.uio_rw = UIO_WRITE; - uio2.uio_td = uio->uio_td; - error = ttwrite(tp, &uio2, flag); - if (error != 0) - break; - free(ibuf, M_SNP); - ibuf = NULL; - } - if (ibuf != NULL) - free(ibuf, M_SNP); - return (error); -} - -static struct tty * -snpdevtotty(struct cdev *dev) -{ - struct cdevsw *cdp; - struct tty *tp; - - cdp = dev_refthread(dev); - if (cdp == NULL) - return (NULL); - if (!(cdp->d_flags & D_TTY)) - tp = NULL; - else - tp = dev->si_tty; - dev_relthread(dev); - return (tp); -} - -#define SNP_INPUT_BUF 5 /* This is even too much, the maximal - * interactive mode write is 3 bytes - * length for function keys... - */ - -static int -snpwrite(struct cdev *dev, struct uio *uio, int flag) -{ - struct snoop *snp; - struct tty *tp; - int error, i, len; - unsigned char c[SNP_INPUT_BUF]; - - error = devfs_get_cdevpriv((void **)&snp); - if (error != 0) - return (error); - - tp = snp->snp_tty; - if (tp == NULL) - return (EIO); - if ((tp->t_state & TS_SNOOP) && tp->t_line == snooplinedisc) - goto tty_input; - - printf("snp: attempt to write to bad tty\n"); - return (EIO); - -tty_input: - if (!(tp->t_state & TS_ISOPEN)) - return (EIO); - - while (uio->uio_resid > 0) { - len = imin(uio->uio_resid, SNP_INPUT_BUF); - if ((error = uiomove(c, len, uio)) != 0) - return (error); - for (i=0; i < len; i++) { - if (ttyinput(c[i], tp)) - return (EIO); - } - } - return (0); -} - - -static int -snpread(struct cdev *dev, struct uio *uio, int flag) -{ - struct snoop *snp; - int error, len, n, nblen, s; - caddr_t from; - char *nbuf; - - error = devfs_get_cdevpriv((void **)&snp); - if (error != 0) - return (error); - - KASSERT(snp->snp_len + snp->snp_base <= snp->snp_blen, - ("snoop buffer error")); - - if (snp->snp_tty == NULL) - return (EIO); - - snp->snp_flags &= ~SNOOP_RWAIT; - - do { - if (snp->snp_len == 0) { - if (flag & O_NONBLOCK) - return (EWOULDBLOCK); - snp->snp_flags |= SNOOP_RWAIT; - error = tsleep(snp, (PZERO + 1) | PCATCH, - "snprd", 0); - if (error != 0) - return (error); - } - } while (snp->snp_len == 0); - - n = snp->snp_len; - - error = 0; - while (snp->snp_len > 0 && uio->uio_resid > 0 && error == 0) { - len = min((unsigned)uio->uio_resid, snp->snp_len); - from = (caddr_t)(snp->snp_buf + snp->snp_base); - if (len == 0) - break; - - error = uiomove(from, len, uio); - snp->snp_base += len; - snp->snp_len -= len; - } - if ((snp->snp_flags & SNOOP_OFLOW) && (n < snp->snp_len)) { - snp->snp_flags &= ~SNOOP_OFLOW; - } - s = spltty(); - nblen = snp->snp_blen; - if (((nblen / 2) >= SNOOP_MINLEN) && (nblen / 2) >= snp->snp_len) { - while (nblen / 2 >= snp->snp_len && nblen / 2 >= SNOOP_MINLEN) - nblen = nblen / 2; - if ((nbuf = malloc(nblen, M_SNP, M_NOWAIT)) != NULL) { - bcopy(snp->snp_buf + snp->snp_base, nbuf, snp->snp_len); - free(snp->snp_buf, M_SNP); - snp->snp_buf = nbuf; - snp->snp_blen = nblen; - snp->snp_base = 0; - } - } - splx(s); - - return (error); -} - -static int -snp_in(struct snoop *snp, char *buf, int n) -{ - int s_free, s_tail; - int s, len, nblen; - caddr_t from, to; - char *nbuf; - - KASSERT(n >= 0, ("negative snoop char count")); - - if (n == 0) - return (0); - - if (snp->snp_flags & SNOOP_DOWN) { - printf("snp: more data to down interface\n"); - return (0); - } - - if (snp->snp_flags & SNOOP_OFLOW) { - printf("snp: buffer overflow\n"); - /* - * On overflow we just repeat the standart close - * procedure...yes , this is waste of space but.. Then next - * read from device will fail if one would recall he is - * snooping and retry... - */ - - return (snp_down(snp)); - } - s_tail = snp->snp_blen - (snp->snp_len + snp->snp_base); - s_free = snp->snp_blen - snp->snp_len; - - - if (n > s_free) { - s = spltty(); - nblen = snp->snp_blen; - while ((n > s_free) && ((nblen * 2) <= SNOOP_MAXLEN)) { - nblen = snp->snp_blen * 2; - s_free = nblen - (snp->snp_len + snp->snp_base); - } - if ((n <= s_free) && (nbuf = malloc(nblen, M_SNP, M_NOWAIT))) { - bcopy(snp->snp_buf + snp->snp_base, nbuf, snp->snp_len); - free(snp->snp_buf, M_SNP); - snp->snp_buf = nbuf; - snp->snp_blen = nblen; - snp->snp_base = 0; - } else { - snp->snp_flags |= SNOOP_OFLOW; - if (snp->snp_flags & SNOOP_RWAIT) { - snp->snp_flags &= ~SNOOP_RWAIT; - wakeup(snp); - } - splx(s); - return (0); - } - splx(s); - } - if (n > s_tail) { - from = (caddr_t)(snp->snp_buf + snp->snp_base); - to = (caddr_t)(snp->snp_buf); - len = snp->snp_len; - bcopy(from, to, len); - snp->snp_base = 0; - } - to = (caddr_t)(snp->snp_buf + snp->snp_base + snp->snp_len); - bcopy(buf, to, n); - snp->snp_len += n; - - if (snp->snp_flags & SNOOP_RWAIT) { - snp->snp_flags &= ~SNOOP_RWAIT; - wakeup(snp); - } - selwakeuppri(&snp->snp_sel, PZERO + 1); - - return (n); -} - static void snp_dtor(void *data) { - struct snoop *snp = data; + struct snp_softc *ss = data; - snp->snp_blen = 0; - LIST_REMOVE(snp, snp_list); - free(snp->snp_buf, M_SNP); - snp->snp_flags &= ~SNOOP_OPEN; - snp_detach(snp); + free(ss, M_SNP); } static int -snpopen(struct cdev *dev, int flag, int mode, struct thread *td) +snp_open(struct cdev *dev, int flag, int mode, struct thread *td) { - struct snoop *snp; - int error; + struct snp_softc *ss; - snp = malloc(sizeof(*snp), M_SNP, M_WAITOK | M_ZERO); - error = devfs_set_cdevpriv(snp, snp_dtor); - if (error != 0) { - free(snp, M_SNP); - return (error); - } - - /* - * We intentionally do not OR flags with SNOOP_OPEN, but set them so - * all previous settings (especially SNOOP_OFLOW) will be cleared. - */ - snp->snp_flags = SNOOP_OPEN; - - snp->snp_buf = malloc(SNOOP_MINLEN, M_SNP, M_WAITOK); - snp->snp_blen = SNOOP_MINLEN; - snp->snp_base = 0; - snp->snp_len = 0; + /* Allocate per-snoop data */ + ss = malloc(sizeof(struct snp_softc), M_SNP, M_WAITOK|M_ZERO); + devfs_set_cdevpriv(ss, snp_dtor); - /* - * snp_tty == NULL is for inactive snoop devices. - */ - snp->snp_tty = NULL; - snp->snp_target = NULL; - - LIST_INSERT_HEAD(&snp_sclist, snp, snp_list); return (0); } - -static void -snp_detach(void *arg) +static int +snp_read(struct cdev *dev, struct uio *uio, int flag) { - struct snoop *snp; - struct tty *tp; - snp = (struct snoop *)arg; - snp->snp_base = 0; - snp->snp_len = 0; - - /* - * If line disc. changed we do not touch this pointer, SLIP/PPP will - * change it anyway. - */ - tp = snp->snp_tty; - if (tp == NULL) - goto detach_notty; - - if ((tp->t_state & TS_SNOOP) && tp->t_line == snooplinedisc) { - tp->t_state &= ~TS_SNOOP; - tp->t_line = snp->snp_olddisc; - } else - printf("snp: bad attached tty data\n"); - - snp->snp_tty = NULL; - snp->snp_target = NULL; - -detach_notty: - selwakeuppri(&snp->snp_sel, PZERO + 1); - if ((snp->snp_flags & SNOOP_OPEN) == 0) - free(snp, M_SNP); + return (EIO); } static int -snp_down(struct snoop *snp) +snp_write(struct cdev *dev, struct uio *uio, int flag) { - if (snp->snp_blen != SNOOP_MINLEN) { - free(snp->snp_buf, M_SNP); - snp->snp_buf = malloc(SNOOP_MINLEN, M_SNP, M_WAITOK); - snp->snp_blen = SNOOP_MINLEN; - } - snp->snp_flags |= SNOOP_DOWN; - snp_detach(snp); - - return (0); + return (EIO); } static int -snpioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags, +snp_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags, struct thread *td) { - struct snoop *snp; - struct tty *tp; - struct cdev *tdev; - struct file *fp; - int error, s; + struct snp_softc *ss; + int error; - error = devfs_get_cdevpriv((void **)&snp); + error = devfs_get_cdevpriv((void **)&ss); if (error != 0) return (error); switch (cmd) { case SNPSTTY: - s = *(int *)data; - if (s < 0) - return (snp_down(snp)); - - if (fget(td, s, &fp) != 0) - return (EINVAL); - if (fp->f_type != DTYPE_VNODE || - fp->f_vnode->v_type != VCHR || - fp->f_vnode->v_rdev == NULL) { - fdrop(fp, td); - return (EINVAL); + /* Bind TTY to snoop instance */ + mtx_lock(&snp_register_mtx); + if (ss->snp_tty != NULL) { + mtx_unlock(&snp_register_mtx); + return (EBUSY); } - tdev = fp->f_vnode->v_rdev; - fdrop(fp, td); - - if (snp->snp_tty != NULL) - return (EBUSY); - - tp = snpdevtotty(tdev); - if (!tp) - return (EINVAL); - if (tp->t_state & TS_SNOOP) - return (EBUSY); - - s = spltty(); - tp->t_state |= TS_SNOOP; - snp->snp_olddisc = tp->t_line; - tp->t_line = snooplinedisc; - snp->snp_tty = tp; - snp->snp_target = tdev; - - /* - * Clean overflow and down flags - - * we'll have a chance to get them in the future :))) - */ - snp->snp_flags &= ~SNOOP_OFLOW; - snp->snp_flags &= ~SNOOP_DOWN; - splx(s); - break; - + error = ttyhook_register(&ss->snp_tty, td, *(int *)data, + &snp_hook, ss); + mtx_unlock(&snp_register_mtx); + return (error); case SNPGTTY: - /* - * We keep snp_target field specially to make - * SNPGTTY happy, else we can't know what is device - * major/minor for tty. - */ - *((dev_t *)data) = dev2udev(snp->snp_target); - break; - - case FIONBIO: - break; - - case FIOASYNC: - if (*(int *)data) - snp->snp_flags |= SNOOP_ASYNC; + /* Obtain device number of associated TTY */ + if (ss->snp_tty == NULL) + *(dev_t *)data = NODEV; else - snp->snp_flags &= ~SNOOP_ASYNC; - break; - - case FIONREAD: - s = spltty(); - if (snp->snp_tty != NULL) - *(int *)data = snp->snp_len; - else - if (snp->snp_flags & SNOOP_DOWN) { - if (snp->snp_flags & SNOOP_OFLOW) - *(int *)data = SNP_OFLOW; - else - *(int *)data = SNP_TTYCLOSE; - } else { - *(int *)data = SNP_DETACH; - } - splx(s); - break; - + *(dev_t *)data = tty_udev(ss->snp_tty); + return (0); default: return (ENOTTY); } - return (0); -} - -static int -snppoll(struct cdev *dev, int events, struct thread *td) -{ - struct snoop *snp; - int revents; - - if (devfs_get_cdevpriv((void **)&snp) != 0) - return (events & - (POLLHUP|POLLIN|POLLRDNORM|POLLOUT|POLLWRNORM)); - - revents = 0; - /* - * If snoop is down, we don't want to poll() forever so we return 1. - * Caller should see if we down via FIONREAD ioctl(). The last should - * return -1 to indicate down state. - */ - if (events & (POLLIN | POLLRDNORM)) { - if (snp->snp_flags & SNOOP_DOWN || snp->snp_len > 0) - revents |= events & (POLLIN | POLLRDNORM); - else - selrecord(td, &snp->snp_sel); - } - return (revents); } static int @@ -611,28 +138,22 @@ switch (type) { case MOD_LOAD: - snooplinedisc = ldisc_register(LDISC_LOAD, &snpdisc); - snoopdev = make_dev(&snp_cdevsw, 0, UID_ROOT, GID_WHEEL, - 0600, "snp"); - /* For compatibility */ - make_dev_alias(snoopdev, "snp0"); - break; + snp_dev = make_dev(&snp_cdevsw, 0, + UID_ROOT, GID_WHEEL, 0600, "snp"); + return (0); case MOD_UNLOAD: - if (!LIST_EMPTY(&snp_sclist)) - return (EBUSY); - destroy_dev(snoopdev); - ldisc_deregister(snooplinedisc); - break; + /* XXX: Make existing users leave. */ + destroy_dev(snp_dev); + return (0); default: return (EOPNOTSUPP); - break; } - return (0); } static moduledata_t snp_mod = { - "snp", - snp_modevent, - NULL + "snp", + snp_modevent, + NULL }; + DECLARE_MODULE(snp, snp_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE); ==== //depot/projects/mpsafetty/sys/kern/tty.c#24 (text+ko) ==== @@ -36,6 +36,7 @@ #include <sys/conf.h> #include <sys/cons.h> #include <sys/fcntl.h> +#include <sys/file.h> #include <sys/filio.h> #ifdef COMPAT_43TTY #include <sys/ioctl_compat.h> @@ -866,7 +867,7 @@ tp = malloc(sizeof(struct tty), M_TTY, M_WAITOK|M_ZERO); tp->t_devsw = tsw; - tp->t_softc = sc; + tp->t_devswsoftc = sc; tp->t_flags = tsw->tsw_flags; tty_init_termios(tp); @@ -1670,6 +1671,60 @@ ttydevsw_inwakeup(tp); } +int +ttyhook_register(struct tty **rtp, struct thread *td, int fd, + struct ttyhook *th, void *softc) +{ + struct tty *tp; + struct file *fp; + struct cdev *dev; + struct cdevsw *cdp; + int error; + + /* Validate the file descriptor */ + if (fget(td, fd, &fp) != 0) + return (EINVAL); + + /* Make sure the vnode is bound to a character device */ + error = EINVAL; + if (fp->f_type != DTYPE_VNODE || fp->f_vnode->v_type != VCHR || + fp->f_vnode->v_rdev == NULL) { + goto done1; + } + dev = fp->f_vnode->v_rdev; + + /* Make sure it is a TTY */ + cdp = dev_refthread(dev); + if (cdp == NULL) + goto done1; + if ((cdp->d_flags & D_TTY) == 0) + goto done2; + tp = dev->si_drv1; + + /* Try to attach the hook to the TTY */ + error = EBUSY; + tty_lock(tp); + MPASS((tp->t_hook == NULL) == ((tp->t_flags & TF_HOOK) == 0)); + if (tp->t_flags & TF_HOOK) + goto done3; + + tp->t_flags |= TF_HOOK; + tp->t_hook = th; + error = 0; + +done3: tty_unlock(tp); +done2: dev_relthread(dev); +done1: fdrop(fp, td); + return (error); +} + +void +ttyhook_unregister(struct tty *tp) +{ + + MPASS(tp->t_flags & TF_HOOK); +} + #include "opt_ddb.h" #ifdef DDB #include <ddb/ddb.h> ==== //depot/projects/mpsafetty/sys/modules/snp/Makefile#2 (text+ko) ==== @@ -3,6 +3,6 @@ .PATH: ${.CURDIR}/../../dev/snp KMOD= snp -SRCS= snp.c vnode_if.h +SRCS= snp.c .include <bsd.kmod.mk> ==== //depot/projects/mpsafetty/sys/sys/tty.h#14 (text+ko) ==== @@ -80,6 +80,7 @@ #define TF_EXCLUDE 0x1000 /* Exclusive access. */ #define TF_BYPASS 0x2000 /* Optimized input path. */ #define TF_ZOMBIE 0x4000 /* Modem disconnect received. */ +#define TF_HOOK 0x8000 /* TTY has hook attached. */ unsigned int t_revokecnt; /* (t) revoke() count. */ /* Buffering mechanisms. */ @@ -111,13 +112,15 @@ struct termios t_termios_lock_out; /* cua%s.lock. */ struct ttydevsw *t_devsw; /* (c) Driver hooks. */ + struct ttyhook *t_hook; /* (t) Capture/inject hook. */ /* Process signal delivery. */ struct pgrp *t_pgrp; /* (t) Foreground process group. */ struct session *t_session; /* (t) Associated session. */ unsigned int t_sessioncnt; /* (t) Backpointing sessions. */ - void *t_softc; /* (c) Soft config, for drivers. */ + void *t_devswsoftc; /* (c) Soft config, for drivers. */ + void *t_hooksoftc; /* (t) Soft config, for hooks. */ struct cdev *t_dev; /* (c) Primary character device. */ }; @@ -179,7 +182,7 @@ dev_t tty_udev(struct tty *); #define tty_opened(tp) ((tp)->t_flags & TF_OPENED) #define tty_gone(tp) ((tp)->t_flags & TF_GONE) -#define tty_softc(tp) ((tp)->t_softc) +#define tty_softc(tp) ((tp)->t_devswsoftc) #define tty_devname(tp) devtoname((tp)->t_dev) /* Status line printing. */ @@ -192,6 +195,7 @@ /* Drivers and line disciplines also need to call these. */ #include <sys/ttydevsw.h> #include <sys/ttydisc.h> +#include <sys/ttyhook.h> #endif /* _KERNEL */ #endif /* !_SYS_TTY_H_ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200808211721.m7LHLY8m069277>