Date: Sun, 20 May 2001 16:48:04 -0700 (PDT) From: dd@freebsd.org To: FreeBSD-gnats-submit@freebsd.org Subject: kern/27481: [PATCH] to make snp(4) a module Message-ID: <200105202348.f4KNm4m01756@spike.unixfreak.org>
next in thread | raw e-mail | index | archive | help
>Number: 27481 >Category: kern >Synopsis: [PATCH] to make snp(4) a module >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Sun May 20 16:50:01 PDT 2001 >Closed-Date: >Last-Modified: >Originator: Dima Dorfman >Release: FreeBSD 5.0-20010519-CURRENT i386 >Organization: Private >Environment: System: FreeBSD spike.unixfreak.org 5.0-20010519-CURRENT FreeBSD 5.0-20010519-CURRENT #4: Sun May 20 14:16:15 PDT 2001 dima@spike.unixfreak.org:/c/home/dima/w/f/c/sys/compile/SPIKE i386 >Description: Right now, snp(4) can't be compiled as a module because it depends on hacks in the tty subsystem similar to the following: #ifdef DEV_SNP if (ISSET(tp->t_state, TS_SNOOP) && tp->t_sc != NULL) snpin((struct snoop *)tp->t_sc, cp, cc); #endif snpin() is a function in snp(4), so it's not simply a matter of removing the #ifdef's. Attached is a patch that converts snp(4) to use line disciplines to get the information it needs. I'm not sure if it's entirely appropriate to use line disciplines this way, but I think it's a lot better than the above code, and it has the fortunate sideaffect that snp(4) can be built as a module. If this gets accepted I'll submit patches to remove the aforementioned tty hacks. >How-To-Repeat: >Fix: I've sent this to both -hackers and -audit; nobody replied. I take this to mean that nobody cares, and my use of line disciplines isn't evil enough to warrant attention. If somebody just wants to review this so I can commit it (I'm not a src/ committer) that'd be fine, too. Index: kern/tty_snoop.c =================================================================== RCS file: /st/src/FreeBSD/src/sys/kern/tty_snoop.c,v retrieving revision 1.53 diff -u -r1.53 tty_snoop.c --- kern/tty_snoop.c 2001/04/17 20:53:11 1.53 +++ kern/tty_snoop.c 2001/05/15 04:15:51 @@ -12,10 +12,9 @@ * * Snoop stuff. * - * $FreeBSD: src/sys/kern/tty_snoop.c,v 1.53 2001/04/17 20:53:11 dd Exp $ + * $FreeBSD$ */ -#include "opt_compat.h" #include <sys/param.h> #include <sys/systm.h> #include <sys/filio.h> @@ -29,6 +28,7 @@ #include <sys/kernel.h> #include <sys/snoop.h> #include <sys/vnode.h> +#include <sys/conf.h> static d_open_t snpopen; static d_close_t snpclose; @@ -61,9 +61,63 @@ static MALLOC_DEFINE(M_SNP, "snp", "Snoop device data"); +#define ttytosnp(t) (struct snoop *)(t)->t_sc static struct tty *snpdevtotty __P((dev_t dev)); static int snp_detach __P((struct snoop *snp)); +/* + * The number of the "snoop" line discipline. This gets determined at + * module load time. + */ +static int mylinedisc; + +static int +dsnwrite(struct tty *tp, struct uio *uio, int flag) +{ + struct snoop *snp = ttytosnp(tp); + int error = 0; + char ibuf[1024]; + int ilen; + struct iovec iov; + struct uio uio2; + + while (uio->uio_resid) { + ilen = MIN(sizeof(ibuf), uio->uio_resid); + error = uiomove(ibuf, ilen, uio); + if (error) + break; + snpin(snp, ibuf, ilen); + /* Hackish, but I think it's 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_procp = uio->uio_procp; + error = ttwrite(tp, &uio2, flag); + if (error) + break; + } + return (error); +} + +/* + * XXX should there be a global version of this? + */ +static int +l_nullioctl(struct tty *tp, u_long cmd, char *data, int flags, struct proc *p) +{ + + return (ENOIOCTL); +} + +static struct linesw snpdisc = { + ttyopen, ttylclose, ttread, dsnwrite, + l_nullioctl, ttyinput, ttstart, ttymodem }; + static struct tty * snpdevtotty (dev) dev_t dev; @@ -98,7 +152,7 @@ tp = snp->snp_tty; if ((tp->t_sc == snp) && (tp->t_state & TS_SNOOP) && - (tp->t_line == OTTYDISC || tp->t_line == NTTYDISC)) + tp->t_line == mylinedisc) goto tty_input; printf("Snoop: attempt to write to bad tty.\n"); @@ -334,9 +388,10 @@ tp = snp->snp_tty; if (tp && (tp->t_sc == snp) && (tp->t_state & TS_SNOOP) && - (tp->t_line == OTTYDISC || tp->t_line == NTTYDISC)) { + tp->t_line == mylinedisc) { tp->t_sc = NULL; tp->t_state &= ~TS_SNOOP; + tp->t_line = snp->snp_olddisc; } else printf("Snoop: bad attached tty data.\n"); @@ -409,12 +464,6 @@ if (!tp) return (EINVAL); - if ((tp->t_sc != (caddr_t)snp) && (tp->t_state & TS_SNOOP)) - return (EBUSY); - - if ((tp->t_line != OTTYDISC) && (tp->t_line != NTTYDISC)) - return (EBUSY); - s = spltty(); if (snp->snp_target == NODEV) { @@ -425,6 +474,8 @@ tp->t_sc = (caddr_t)snp; tp->t_state |= TS_SNOOP; + snp->snp_olddisc = tp->t_line; + tp->t_line = mylinedisc; snp->snp_tty = tp; snp->snp_target = tdev; @@ -503,8 +554,6 @@ return (revents); } -static void snp_drvinit __P((void *unused)); - static void snp_clone(void *arg, char *name, int namelen, dev_t *dev) { @@ -519,13 +568,31 @@ return; } -static void -snp_drvinit(unused) - void *unused; +static int +snp_modevent(module_t mod, int type, void *data) { + static eventhandler_tag eh_tag = NULL; - EVENTHANDLER_REGISTER(dev_clone, snp_clone, 0, 1000); - cdevsw_add(&snp_cdevsw); + switch (type) { + case MOD_LOAD: + eh_tag = EVENTHANDLER_REGISTER(dev_clone, snp_clone, 0, 1000); + mylinedisc = ldisc_register(LDISC_LOAD, &snpdisc); + cdevsw_add(&snp_cdevsw); + break; + case MOD_UNLOAD: + EVENTHANDLER_DEREGISTER(dev_clone, eh_tag); + ldisc_deregister(mylinedisc); + cdevsw_remove(&snp_cdevsw); + break; + default: + break; + } + return 0; } -SYSINIT(snpdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,snp_drvinit,NULL) +static moduledata_t snp_mod = { + "snp", + snp_modevent, + NULL +}; +DECLARE_MODULE(snp, snp_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE+CDEV_MAJOR); Index: sys/snoop.h =================================================================== RCS file: /st/src/FreeBSD/src/sys/sys/snoop.h,v retrieving revision 1.14 diff -u -r1.14 snoop.h --- sys/snoop.h 1999/12/29 04:24:47 1.14 +++ sys/snoop.h 2001/05/15 04:15:51 @@ -54,6 +54,7 @@ #define SNOOP_OFLOW 0x0010 #define SNOOP_DOWN 0x0020 struct selinfo snp_sel; /* Selection info */ + int snp_olddisc; /* Old line discipline */ }; /* XXX several wrong storage classes and types here. */ >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200105202348.f4KNm4m01756>