From owner-p4-projects@FreeBSD.ORG Sat Sep 20 08:28:38 2008 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id A57AF1065675; Sat, 20 Sep 2008 08:28:38 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 5EE88106566C for ; Sat, 20 Sep 2008 08:28:38 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 4A4F98FC16 for ; Sat, 20 Sep 2008 08:28:38 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id m8K8ScgU097638 for ; Sat, 20 Sep 2008 08:28:38 GMT (envelope-from ed@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id m8K8Sc85097632 for perforce@freebsd.org; Sat, 20 Sep 2008 08:28:38 GMT (envelope-from ed@FreeBSD.org) Date: Sat, 20 Sep 2008 08:28:38 GMT Message-Id: <200809200828.m8K8Sc85097632@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to ed@FreeBSD.org using -f From: Ed Schouten To: Perforce Change Reviews Cc: Subject: PERFORCE change 150152 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 20 Sep 2008 08:28:38 -0000 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_ */