Skip site navigation (1)Skip section navigation (2)
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>