Date: Sat, 20 Sep 2008 08:28:38 GMT From: Ed Schouten <ed@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 150152 for review Message-ID: <200809200828.m8K8Sc85097632@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=150152 Change 150152 by ed@ed_dull on 2008/09/20 08:27:37 Add additional TTY hooks, so we can get all the line disciplines working again. Requested by: thompsa Affected files ... .. //depot/projects/mpsafetty/sys/kern/tty_ttydisc.c#22 edit .. //depot/projects/mpsafetty/sys/sys/ttydisc.h#8 edit .. //depot/projects/mpsafetty/sys/sys/ttyhook.h#6 edit Differences ... ==== //depot/projects/mpsafetty/sys/kern/tty_ttydisc.c#22 (text+ko) ==== @@ -102,6 +102,9 @@ ttydevsw_inwakeup(tp); ttydevsw_outwakeup(tp); } + + if (ttyhook_hashook(tp, close)) + ttyhook_close(tp); } static int @@ -820,6 +823,9 @@ tty_lock_assert(tp, MA_OWNED); atomic_add_long(&tty_nin, 1); + + if (ttyhook_hashook(tp, rint)) + return ttyhook_rint(tp, c, flags); if (tp->t_flags & TF_BYPASS) goto processed; @@ -1037,7 +1043,7 @@ } size_t -ttydisc_rint_bypass(struct tty *tp, char *buf, size_t len) +ttydisc_rint_bypass(struct tty *tp, const void *buf, size_t len) { size_t ret; @@ -1047,6 +1053,9 @@ atomic_add_long(&tty_nin, len); + if (ttyhook_hashook(tp, rint_bypass)) + return ttyhook_rint_bypass(tp, buf, len); + ret = ttyinq_write(&tp->t_inq, buf, len, 0); ttyinq_canonicalize(&tp->t_inq); @@ -1065,6 +1074,29 @@ ttydevsw_outwakeup(tp); } +size_t +ttydisc_rint_poll(struct tty *tp) +{ + size_t l; + + tty_lock_assert(tp, MA_OWNED); + + if (ttyhook_hashook(tp, rint_poll)) + return ttyhook_rint_poll(tp); + + /* + * XXX: Still allow character input when there's no space in the + * buffers, but we haven't entered the high watermark. This is + * to allow backspace characters to be inserted when in + * canonical mode. + */ + l = ttyinq_bytesleft(&tp->t_inq); + if (l == 0 && (tp->t_flags & TF_HIWAT_IN) == 0) + return (1); + + return (l); +} + static void ttydisc_wakeup_watermark(struct tty *tp) { @@ -1095,6 +1127,9 @@ if (tp->t_flags & TF_STOPPED) return (0); + if (ttyhook_hashook(tp, getc_inject)) + return ttyhook_getc_inject(tp, buf, len); + len = ttyoutq_read(&tp->t_outq, buf, len); if (ttyhook_hashook(tp, getc_capture)) @@ -1124,7 +1159,8 @@ * copying to userspace. Just call ttydisc_getc() and * temporarily store data in a shadow buffer. */ - if (ttyhook_hashook(tp, getc_capture)) { + if (ttyhook_hashook(tp, getc_capture) || + ttyhook_hashook(tp, getc_inject)) { while (uio->uio_resid > 0) { /* Read to shadow buffer. */ len = ttydisc_getc(tp, buf, @@ -1150,6 +1186,21 @@ return (error); } +size_t +ttydisc_getc_poll(struct tty *tp) +{ + + tty_lock_assert(tp, MA_OWNED); + + if (tp->t_flags & TF_STOPPED) + return (0); + + if (ttyhook_hashook(tp, getc_poll)) + return ttyhook_getc_poll(tp); + + return ttyoutq_bytesused(&tp->t_outq); +} + /* * XXX: not really related to the TTYDISC, but we'd better put * tty_putchar() here, because we need to perform proper output ==== //depot/projects/mpsafetty/sys/sys/ttydisc.h#8 (text+ko) ==== @@ -52,10 +52,12 @@ void ttydisc_modem(struct tty *, int); #define ttydisc_can_bypass(tp) ((tp)->t_flags & TF_BYPASS) int ttydisc_rint(struct tty *, char, int); -size_t ttydisc_rint_bypass(struct tty *, char *, size_t); +size_t ttydisc_rint_bypass(struct tty *, const void *, size_t); void ttydisc_rint_done(struct tty *); +size_t ttydisc_rint_poll(struct tty *); size_t ttydisc_getc(struct tty *, void *, size_t); int ttydisc_getc_uio(struct tty *, struct uio *); +size_t ttydisc_getc_poll(struct tty *); /* Error codes for ttydisc_rint(). */ #define TRE_FRAMING 0x01 @@ -81,36 +83,4 @@ return ttyoutq_bytesleft(&tp->t_outq); } -static __inline size_t -ttydisc_rint_poll(struct tty *tp) -{ - size_t l; - - tty_lock_assert(tp, MA_OWNED); - - /* - * XXX: Still allow character input when there's no space in the - * buffers, but we haven't entered the high watermark. This is - * to allow backspace characters to be inserted when in - * canonical mode. - */ - l = ttyinq_bytesleft(&tp->t_inq); - if (l == 0 && (tp->t_flags & TF_HIWAT_IN) == 0) - return (1); - - return (l); -} - -static __inline size_t -ttydisc_getc_poll(struct tty *tp) -{ - - tty_lock_assert(tp, MA_OWNED); - - if (tp->t_flags & TF_STOPPED) - return (0); - - return ttyoutq_bytesused(&tp->t_outq); -} - #endif /* !_SYS_TTYDISC_H_ */ ==== //depot/projects/mpsafetty/sys/sys/ttyhook.h#6 (text+ko) ==== @@ -39,10 +39,29 @@ * Hooks interface, which allows to capture and inject traffic into the * input and output paths of a TTY. */ + +typedef int th_rint_t(struct tty *, char, int); +typedef size_t th_rint_bypass_t(struct tty *, const void *, size_t); +typedef size_t th_rint_poll_t(struct tty *); + +typedef size_t th_getc_inject_t(struct tty *, void *, size_t); typedef void th_getc_capture_t(struct tty *, const void *, size_t); +typedef size_t th_getc_poll_t(struct tty *); + +typedef void th_close_t(struct tty *); struct ttyhook { + /* Character input. */ + th_rint_t *th_rint; + th_rint_bypass_t *th_rint_bypass; + th_rint_poll_t *th_rint_poll; + + /* Character output. */ + th_getc_inject_t *th_getc_inject; th_getc_capture_t *th_getc_capture; + th_getc_poll_t *th_getc_poll; + + th_close_t *th_close; }; int ttyhook_register(struct tty **, struct thread *, int, @@ -52,6 +71,42 @@ #define ttyhook_hashook(tp,hook) ((tp)->t_hook != NULL && \ (tp)->t_hook->th_ ## hook != NULL) +static __inline int +ttyhook_rint(struct tty *tp, char c, int flags) +{ + tty_lock_assert(tp, MA_OWNED); + MPASS(!tty_gone(tp)); + + return tp->t_hook->th_rint(tp, c, flags); +} + +static __inline size_t +ttyhook_rint_bypass(struct tty *tp, const void *buf, size_t len) +{ + tty_lock_assert(tp, MA_OWNED); + MPASS(!tty_gone(tp)); + + return tp->t_hook->th_rint_bypass(tp, buf, len); +} + +static __inline size_t +ttyhook_rint_poll(struct tty *tp) +{ + tty_lock_assert(tp, MA_OWNED); + MPASS(!tty_gone(tp)); + + return tp->t_hook->th_rint_poll(tp); +} + +static __inline size_t +ttyhook_getc_inject(struct tty *tp, void *buf, size_t len) +{ + tty_lock_assert(tp, MA_OWNED); + MPASS(!tty_gone(tp)); + + return tp->t_hook->th_getc_inject(tp, buf, len); +} + static __inline void ttyhook_getc_capture(struct tty *tp, const void *buf, size_t len) { @@ -61,4 +116,21 @@ tp->t_hook->th_getc_capture(tp, buf, len); } +static __inline size_t +ttyhook_getc_poll(struct tty *tp) +{ + tty_lock_assert(tp, MA_OWNED); + MPASS(!tty_gone(tp)); + + return tp->t_hook->th_getc_poll(tp); +} + +static __inline void +ttyhook_close(struct tty *tp) +{ + tty_lock_assert(tp, MA_OWNED); + + tp->t_hook->th_close(tp); +} + #endif /* !_SYS_TTYHOOK_H_ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200809200828.m8K8Sc85097632>
