Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 21 Aug 2008 18:50:10 GMT
From:      Ed Schouten <ed@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 148025 for review
Message-ID:  <200808211850.m7LIoABw086066@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=148025

Change 148025 by ed@ed_flippo on 2008/08/21 18:49:46

	Actually make diversion of outgoing data work. Also fix some
	style issues, etc.

Affected files ...

.. //depot/projects/mpsafetty/sys/dev/snp/snp.c#6 edit
.. //depot/projects/mpsafetty/sys/kern/tty.c#27 edit
.. //depot/projects/mpsafetty/sys/kern/tty_ttydisc.c#12 edit
.. //depot/projects/mpsafetty/sys/sys/ttyhook.h#2 edit
.. //depot/projects/mpsafetty/sys/sys/ttyqueue.h#5 edit

Differences ...

==== //depot/projects/mpsafetty/sys/dev/snp/snp.c#6 (text+ko) ====

@@ -39,12 +39,15 @@
 #include <sys/uio.h>
 
 static struct cdev	*snp_dev;
+/* XXX: should be mtx, but TTY can be locked by Giant. */
 static struct sx	snp_register_lock;
-/* XXX: should be mtx, but TTY can be locked by Giant */
 SX_SYSINIT(snp_register_lock, &snp_register_lock,
     "tty snoop registration");
 static MALLOC_DEFINE(M_SNP, "snp", "tty snoop device");
 
+#define SNP_INPUT_BUFSIZE	16	/* For uiomove(). */
+#define SNP_OUTPUT_BUFSIZE	4096	/* For the ttyoutq. */
+
 static d_open_t		snp_open;
 static d_read_t		snp_read;
 static d_write_t	snp_write;
@@ -59,11 +62,22 @@
 	.d_name =	"snp",
 };
 
-static struct ttyhook snp_hook; /* XXX */
+static th_getc_capture_t	snp_getc_capture;
+
+static struct ttyhook snp_hook = {
+	.th_getc_capture	= snp_getc_capture,
+};
 
+/*
+ * Per-instance structure.
+ *
+ * List of locks
+ * (r)	locked by snp_register_lock on assignment
+ * (t)	locked by tty_lock
+ */
 struct snp_softc {
-	struct tty	*snp_tty;
-	/* XXX */
+	struct tty	*snp_tty;	/* (r) TTY we're snooping. */
+	struct ttyoutq	snp_outq;	/* (t) Output queue. */
 };
 
 static void
@@ -75,19 +89,31 @@
 	tp = ss->snp_tty;
 	if (tp != NULL) {
 		tty_lock(tp);
+
+		/* Deallocate buffers. */
+		ttyoutq_flush(&ss->snp_outq);
+		ttyoutq_setsize(&ss->snp_outq, NULL, 0);
+		MPASS(ttyoutq_getsize(&ss->snp_outq) == 0);
+
 		ttyhook_unregister(tp);
 	}
 
 	free(ss, M_SNP);
 }
 
+/*
+ * Snoop device node routines.
+ */
+
 static int
 snp_open(struct cdev *dev, int flag, int mode, struct thread *td)
 {
 	struct snp_softc *ss;
 
-	/* Allocate per-snoop data */
+	/* Allocate per-snoop data. */
 	ss = malloc(sizeof(struct snp_softc), M_SNP, M_WAITOK|M_ZERO);
+	ttyoutq_init(&ss->snp_outq);
+
 	devfs_set_cdevpriv(ss, snp_dtor);
 
 	return (0);
@@ -106,7 +132,7 @@
 	struct snp_softc *ss;
 	struct tty *tp;
 	int error, len, i;
-	char in[8];
+	char in[SNP_INPUT_BUFSIZE];
 
 	error = devfs_get_cdevpriv((void **)&ss);
 	if (error != 0)
@@ -117,7 +143,7 @@
 		return (EIO);
 
 	while (uio->uio_resid > 0) {
-		/* Read new data */
+		/* Read new data. */
 		len = imin(uio->uio_resid, sizeof in);
 		error = uiomove(in, len, uio);
 		if (error != 0)
@@ -155,6 +181,7 @@
     struct thread *td)
 {
 	struct snp_softc *ss;
+	struct tty *tp;
 	int error;
 
 	error = devfs_get_cdevpriv((void **)&ss);
@@ -163,7 +190,7 @@
 
 	switch (cmd) {
 	case SNPSTTY:
-		/* Bind TTY to snoop instance */
+		/* Bind TTY to snoop instance. */
 		sx_xlock(&snp_register_lock);
 		if (ss->snp_tty != NULL) {
 			sx_xunlock(&snp_register_lock);
@@ -172,9 +199,16 @@
 		error = ttyhook_register(&ss->snp_tty, td, *(int *)data,
 		    &snp_hook, ss);
 		sx_xunlock(&snp_register_lock);
+
+		/* Now that went okay, allocate a buffer for the queue. */
+		tp = ss->snp_tty;
+		tty_lock(tp);
+		ttyoutq_setsize(&ss->snp_outq, tp, SNP_OUTPUT_BUFSIZE);
+		tty_unlock(tp);
+
 		return (error);
 	case SNPGTTY:
-		/* Obtain device number of associated TTY */
+		/* Obtain device number of associated TTY. */
 		if (ss->snp_tty == NULL)
 			*(dev_t *)data = NODEV;
 		else
@@ -185,6 +219,10 @@
 	}
 }
 
+/*
+ * TTY hook events.
+ */
+
 static int
 snp_modevent(module_t mod, int type, void *data)
 {
@@ -203,6 +241,15 @@
 	}
 }
 
+static void
+snp_getc_capture(struct tty *tp, const void *buf, size_t len)
+{
+	struct snp_softc *ss = ttyhook_softc(tp);
+
+	printf("Added %zu bytes\n", len);
+	ttyoutq_write(&ss->snp_outq, buf, len);
+}
+
 static moduledata_t snp_mod = {
 	"snp",
 	snp_modevent,

==== //depot/projects/mpsafetty/sys/kern/tty.c#27 (text+ko) ====

@@ -877,8 +877,8 @@
 	cv_init(&tp->t_bgwait, "tty background");
 	cv_init(&tp->t_dcdwait, "tty dcd");
 
-	TAILQ_INIT(&tp->t_inq.ti_list);
-	STAILQ_INIT(&tp->t_outq.to_list);
+	ttyinq_init(&tp->t_inq);
+	ttyoutq_init(&tp->t_outq);
 
 	/* Allow drivers to use a custom mutex to lock the TTY. */
 	if (mutex != NULL) {
@@ -1710,6 +1710,7 @@
 
 	tp->t_flags |= TF_HOOK;
 	tp->t_hook = th;
+	tp->t_hooksoftc = softc;
 	*rtp = tp;
 	error = 0;
 

==== //depot/projects/mpsafetty/sys/kern/tty_ttydisc.c#12 (text+ko) ====

@@ -1074,19 +1074,22 @@
 size_t
 ttydisc_getc(struct tty *tp, void *buf, size_t len)
 {
-	int ret;
 
 	tty_lock_assert(tp, MA_OWNED);
 
 	if (tp->t_flags & TF_STOPPED)
 		return (0);
 
-	ret = ttyoutq_read(&tp->t_outq, buf, len);
+	len = ttyoutq_read(&tp->t_outq, buf, len);
 	ttydisc_wakeup_watermark(tp);
 
-	atomic_add_long(&tty_nout, ret);
+	atomic_add_long(&tty_nout, len);
+
+	/* Invoke TTY hooks. XXX: ttyhook_getc_capture()? */
+	if (tp->t_hook != NULL && tp->t_hook->th_getc_capture != NULL)
+		tp->t_hook->th_getc_capture(tp, buf, len);
 
-	return (ret);
+	return (len);
 }
 
 int

==== //depot/projects/mpsafetty/sys/sys/ttyhook.h#2 (text+ko) ====

@@ -42,10 +42,10 @@
  * Hooks interface, which allows to capture and inject traffic into the
  * input and output paths of a TTY.
  */
+typedef void th_getc_capture_t(struct tty *, const void *, size_t);
 
 struct ttyhook {
-	/* XXX */
-	char __dummy;
+	th_getc_capture_t	*th_getc_capture;
 };
 
 int	ttyhook_register(struct tty **, struct thread *, int,

==== //depot/projects/mpsafetty/sys/sys/ttyqueue.h#5 (text+ko) ====

@@ -80,6 +80,13 @@
 void	ttyinq_reprintpos_set(struct ttyinq *);
 void	ttyinq_reprintpos_reset(struct ttyinq *);
 
+static __inline void
+ttyinq_init(struct ttyinq *ti)
+{
+
+	TAILQ_INIT(&ti->ti_list);
+}
+
 static __inline size_t
 ttyinq_getsize(struct ttyinq *ti)
 {
@@ -129,6 +136,13 @@
 size_t	ttyoutq_write(struct ttyoutq *, const void *, size_t);
 int	ttyoutq_write_nofrag(struct ttyoutq *, const void *, size_t);
 
+static __inline void
+ttyoutq_init(struct ttyoutq *to)
+{
+
+	STAILQ_INIT(&to->to_list);
+}
+
 static __inline size_t
 ttyoutq_getsize(struct ttyoutq *to)
 {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200808211850.m7LIoABw086066>