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>
index | next in thread | raw e-mail
>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
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200105202348.f4KNm4m01756>
