PERFORCE change 148025 for review
Ed Schouten
ed at FreeBSD.org
Thu Aug 21 18:50:11 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=148025
Change 148025 by ed at 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)
{
More information about the p4-projects
mailing list