Date: Mon, 14 May 2001 21:53:42 -0700 From: Dima Dorfman <dima@unixfreak.org> To: hackers@freebsd.org Subject: Making snp(4) a module Message-ID: <20010515045342.6B5133E0B@bazooka.unixfreak.org>
next in thread | raw e-mail | index | archive | help
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.
Comments?
Thanks,
Dima Dorfman
dima@unixfreak.org
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. */
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010515045342.6B5133E0B>
