|
Lines 12-21
Link Here
|
| 12 |
* |
12 |
* |
| 13 |
* Snoop stuff. |
13 |
* Snoop stuff. |
| 14 |
* |
14 |
* |
| 15 |
* $FreeBSD: src/sys/kern/tty_snoop.c,v 1.53 2001/04/17 20:53:11 dd Exp $ |
15 |
* $FreeBSD$ |
| 16 |
*/ |
16 |
*/ |
| 17 |
|
17 |
|
| 18 |
#include "opt_compat.h" |
|
|
| 19 |
#include <sys/param.h> |
18 |
#include <sys/param.h> |
| 20 |
#include <sys/systm.h> |
19 |
#include <sys/systm.h> |
| 21 |
#include <sys/filio.h> |
20 |
#include <sys/filio.h> |
|
Lines 29-34
Link Here
|
| 29 |
#include <sys/kernel.h> |
28 |
#include <sys/kernel.h> |
| 30 |
#include <sys/snoop.h> |
29 |
#include <sys/snoop.h> |
| 31 |
#include <sys/vnode.h> |
30 |
#include <sys/vnode.h> |
|
|
31 |
#include <sys/conf.h> |
| 32 |
|
32 |
|
| 33 |
static d_open_t snpopen; |
33 |
static d_open_t snpopen; |
| 34 |
static d_close_t snpclose; |
34 |
static d_close_t snpclose; |
|
Lines 61-69
Link Here
|
| 61 |
|
61 |
|
| 62 |
static MALLOC_DEFINE(M_SNP, "snp", "Snoop device data"); |
62 |
static MALLOC_DEFINE(M_SNP, "snp", "Snoop device data"); |
| 63 |
|
63 |
|
|
|
64 |
#define ttytosnp(t) (struct snoop *)(t)->t_sc |
| 64 |
static struct tty *snpdevtotty __P((dev_t dev)); |
65 |
static struct tty *snpdevtotty __P((dev_t dev)); |
| 65 |
static int snp_detach __P((struct snoop *snp)); |
66 |
static int snp_detach __P((struct snoop *snp)); |
| 66 |
|
67 |
|
|
|
68 |
/* |
| 69 |
* The number of the "snoop" line discipline. This gets determined at |
| 70 |
* module load time. |
| 71 |
*/ |
| 72 |
static int mylinedisc; |
| 73 |
|
| 74 |
static int |
| 75 |
dsnwrite(struct tty *tp, struct uio *uio, int flag) |
| 76 |
{ |
| 77 |
struct snoop *snp = ttytosnp(tp); |
| 78 |
int error = 0; |
| 79 |
char ibuf[1024]; |
| 80 |
int ilen; |
| 81 |
struct iovec iov; |
| 82 |
struct uio uio2; |
| 83 |
|
| 84 |
while (uio->uio_resid) { |
| 85 |
ilen = MIN(sizeof(ibuf), uio->uio_resid); |
| 86 |
error = uiomove(ibuf, ilen, uio); |
| 87 |
if (error) |
| 88 |
break; |
| 89 |
snpin(snp, ibuf, ilen); |
| 90 |
/* Hackish, but I think it's the least of all evils. */ |
| 91 |
iov.iov_base = ibuf; |
| 92 |
iov.iov_len = ilen; |
| 93 |
uio2.uio_iov = &iov; |
| 94 |
uio2.uio_iovcnt = 1; |
| 95 |
uio2.uio_offset = 0; |
| 96 |
uio2.uio_resid = ilen; |
| 97 |
uio2.uio_segflg = UIO_SYSSPACE; |
| 98 |
uio2.uio_rw = UIO_WRITE; |
| 99 |
uio2.uio_procp = uio->uio_procp; |
| 100 |
error = ttwrite(tp, &uio2, flag); |
| 101 |
if (error) |
| 102 |
break; |
| 103 |
} |
| 104 |
return (error); |
| 105 |
} |
| 106 |
|
| 107 |
/* |
| 108 |
* XXX should there be a global version of this? |
| 109 |
*/ |
| 110 |
static int |
| 111 |
l_nullioctl(struct tty *tp, u_long cmd, char *data, int flags, struct proc *p) |
| 112 |
{ |
| 113 |
|
| 114 |
return (ENOIOCTL); |
| 115 |
} |
| 116 |
|
| 117 |
static struct linesw snpdisc = { |
| 118 |
ttyopen, ttylclose, ttread, dsnwrite, |
| 119 |
l_nullioctl, ttyinput, ttstart, ttymodem }; |
| 120 |
|
| 67 |
static struct tty * |
121 |
static struct tty * |
| 68 |
snpdevtotty (dev) |
122 |
snpdevtotty (dev) |
| 69 |
dev_t dev; |
123 |
dev_t dev; |
|
Lines 98-104
Link Here
|
| 98 |
tp = snp->snp_tty; |
152 |
tp = snp->snp_tty; |
| 99 |
|
153 |
|
| 100 |
if ((tp->t_sc == snp) && (tp->t_state & TS_SNOOP) && |
154 |
if ((tp->t_sc == snp) && (tp->t_state & TS_SNOOP) && |
| 101 |
(tp->t_line == OTTYDISC || tp->t_line == NTTYDISC)) |
155 |
tp->t_line == mylinedisc) |
| 102 |
goto tty_input; |
156 |
goto tty_input; |
| 103 |
|
157 |
|
| 104 |
printf("Snoop: attempt to write to bad tty.\n"); |
158 |
printf("Snoop: attempt to write to bad tty.\n"); |
|
Lines 334-342
Link Here
|
| 334 |
tp = snp->snp_tty; |
388 |
tp = snp->snp_tty; |
| 335 |
|
389 |
|
| 336 |
if (tp && (tp->t_sc == snp) && (tp->t_state & TS_SNOOP) && |
390 |
if (tp && (tp->t_sc == snp) && (tp->t_state & TS_SNOOP) && |
| 337 |
(tp->t_line == OTTYDISC || tp->t_line == NTTYDISC)) { |
391 |
tp->t_line == mylinedisc) { |
| 338 |
tp->t_sc = NULL; |
392 |
tp->t_sc = NULL; |
| 339 |
tp->t_state &= ~TS_SNOOP; |
393 |
tp->t_state &= ~TS_SNOOP; |
|
|
394 |
tp->t_line = snp->snp_olddisc; |
| 340 |
} else |
395 |
} else |
| 341 |
printf("Snoop: bad attached tty data.\n"); |
396 |
printf("Snoop: bad attached tty data.\n"); |
| 342 |
|
397 |
|
|
Lines 409-420
Link Here
|
| 409 |
if (!tp) |
464 |
if (!tp) |
| 410 |
return (EINVAL); |
465 |
return (EINVAL); |
| 411 |
|
466 |
|
| 412 |
if ((tp->t_sc != (caddr_t)snp) && (tp->t_state & TS_SNOOP)) |
|
|
| 413 |
return (EBUSY); |
| 414 |
|
| 415 |
if ((tp->t_line != OTTYDISC) && (tp->t_line != NTTYDISC)) |
| 416 |
return (EBUSY); |
| 417 |
|
| 418 |
s = spltty(); |
467 |
s = spltty(); |
| 419 |
|
468 |
|
| 420 |
if (snp->snp_target == NODEV) { |
469 |
if (snp->snp_target == NODEV) { |
|
Lines 425-430
Link Here
|
| 425 |
|
474 |
|
| 426 |
tp->t_sc = (caddr_t)snp; |
475 |
tp->t_sc = (caddr_t)snp; |
| 427 |
tp->t_state |= TS_SNOOP; |
476 |
tp->t_state |= TS_SNOOP; |
|
|
477 |
snp->snp_olddisc = tp->t_line; |
| 478 |
tp->t_line = mylinedisc; |
| 428 |
snp->snp_tty = tp; |
479 |
snp->snp_tty = tp; |
| 429 |
snp->snp_target = tdev; |
480 |
snp->snp_target = tdev; |
| 430 |
|
481 |
|
|
Lines 503-510
Link Here
|
| 503 |
return (revents); |
554 |
return (revents); |
| 504 |
} |
555 |
} |
| 505 |
|
556 |
|
| 506 |
static void snp_drvinit __P((void *unused)); |
|
|
| 507 |
|
| 508 |
static void |
557 |
static void |
| 509 |
snp_clone(void *arg, char *name, int namelen, dev_t *dev) |
558 |
snp_clone(void *arg, char *name, int namelen, dev_t *dev) |
| 510 |
{ |
559 |
{ |
|
Lines 519-531
Link Here
|
| 519 |
return; |
568 |
return; |
| 520 |
} |
569 |
} |
| 521 |
|
570 |
|
| 522 |
static void |
571 |
static int |
| 523 |
snp_drvinit(unused) |
572 |
snp_modevent(module_t mod, int type, void *data) |
| 524 |
void *unused; |
|
|
| 525 |
{ |
573 |
{ |
|
|
574 |
static eventhandler_tag eh_tag = NULL; |
| 526 |
|
575 |
|
| 527 |
EVENTHANDLER_REGISTER(dev_clone, snp_clone, 0, 1000); |
576 |
switch (type) { |
| 528 |
cdevsw_add(&snp_cdevsw); |
577 |
case MOD_LOAD: |
|
|
578 |
eh_tag = EVENTHANDLER_REGISTER(dev_clone, snp_clone, 0, 1000); |
| 579 |
mylinedisc = ldisc_register(LDISC_LOAD, &snpdisc); |
| 580 |
cdevsw_add(&snp_cdevsw); |
| 581 |
break; |
| 582 |
case MOD_UNLOAD: |
| 583 |
EVENTHANDLER_DEREGISTER(dev_clone, eh_tag); |
| 584 |
ldisc_deregister(mylinedisc); |
| 585 |
cdevsw_remove(&snp_cdevsw); |
| 586 |
break; |
| 587 |
default: |
| 588 |
break; |
| 589 |
} |
| 590 |
return 0; |
| 529 |
} |
591 |
} |
| 530 |
|
592 |
|
| 531 |
SYSINIT(snpdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,snp_drvinit,NULL) |
593 |
static moduledata_t snp_mod = { |
|
|
594 |
"snp", |
| 595 |
snp_modevent, |
| 596 |
NULL |
| 597 |
}; |
| 598 |
DECLARE_MODULE(snp, snp_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE+CDEV_MAJOR); |