Fri Sep 23 23:57:06 2011 UTC ()
Fix various bogus things:
- Don't use TTYHOG - 1, you can use the last byte in the ring buffer.
- Don't put unnecessary if statements around the code. The loop invariant
  is that if you reach the top of the loop, cc == 0.
- Remove cast to (void *).
- Check result of b_to_q and adjust cc.
- Explain what the TTYHOG - 2 code tried to do, and do it right.


(christos)
diff -r1.129 -r1.130 src/sys/kern/tty_pty.c

cvs diff -r1.129 -r1.130 src/sys/kern/tty_pty.c (expand / switch to unified diff)

--- src/sys/kern/tty_pty.c 2011/07/26 13:14:18 1.129
+++ src/sys/kern/tty_pty.c 2011/09/23 23:57:06 1.130
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: tty_pty.c,v 1.129 2011/07/26 13:14:18 yamt Exp $ */ 1/* $NetBSD: tty_pty.c,v 1.130 2011/09/23 23:57:06 christos Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1982, 1986, 1989, 1993 4 * Copyright (c) 1982, 1986, 1989, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -27,27 +27,27 @@ @@ -27,27 +27,27 @@
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE. 29 * SUCH DAMAGE.
30 * 30 *
31 * @(#)tty_pty.c 8.4 (Berkeley) 2/20/95 31 * @(#)tty_pty.c 8.4 (Berkeley) 2/20/95
32 */ 32 */
33 33
34/* 34/*
35 * Pseudo-teletype Driver 35 * Pseudo-teletype Driver
36 * (Actually two drivers, requiring two entries in 'cdevsw') 36 * (Actually two drivers, requiring two entries in 'cdevsw')
37 */ 37 */
38 38
39#include <sys/cdefs.h> 39#include <sys/cdefs.h>
40__KERNEL_RCSID(0, "$NetBSD: tty_pty.c,v 1.129 2011/07/26 13:14:18 yamt Exp $"); 40__KERNEL_RCSID(0, "$NetBSD: tty_pty.c,v 1.130 2011/09/23 23:57:06 christos Exp $");
41 41
42#include "opt_ptm.h" 42#include "opt_ptm.h"
43 43
44#include <sys/param.h> 44#include <sys/param.h>
45#include <sys/systm.h> 45#include <sys/systm.h>
46#include <sys/ioctl.h> 46#include <sys/ioctl.h>
47#include <sys/ioctl_compat.h> 47#include <sys/ioctl_compat.h>
48#include <sys/proc.h> 48#include <sys/proc.h>
49#include <sys/tty.h> 49#include <sys/tty.h>
50#include <sys/stat.h> 50#include <sys/stat.h>
51#include <sys/file.h> 51#include <sys/file.h>
52#include <sys/kernel.h> 52#include <sys/kernel.h>
53#include <sys/vnode.h> 53#include <sys/vnode.h>
@@ -691,90 +691,94 @@ ptcwrite(dev_t dev, struct uio *uio, int @@ -691,90 +691,94 @@ ptcwrite(dev_t dev, struct uio *uio, int
691 u_char *cp = NULL; 691 u_char *cp = NULL;
692 int cc = 0; 692 int cc = 0;
693 u_char locbuf[BUFSIZ]; 693 u_char locbuf[BUFSIZ];
694 int cnt = 0; 694 int cnt = 0;
695 int error = 0; 695 int error = 0;
696 696
697again: 697again:
698 mutex_spin_enter(&tty_lock); 698 mutex_spin_enter(&tty_lock);
699 if (!ISSET(tp->t_state, TS_ISOPEN)) 699 if (!ISSET(tp->t_state, TS_ISOPEN))
700 goto block; 700 goto block;
701 if (pti->pt_flags & PF_REMOTE) { 701 if (pti->pt_flags & PF_REMOTE) {
702 if (tp->t_canq.c_cc) 702 if (tp->t_canq.c_cc)
703 goto block; 703 goto block;
704 while (uio->uio_resid > 0 && tp->t_canq.c_cc < TTYHOG - 1) { 704 while (uio->uio_resid > 0 && tp->t_canq.c_cc < TTYHOG) {
705 if (cc == 0) { 
706 cc = min(uio->uio_resid, BUFSIZ); 
707 cc = min(cc, TTYHOG - 1 - tp->t_canq.c_cc); 
708 cp = locbuf; 
709 mutex_spin_exit(&tty_lock); 
710 error = uiomove((void *)cp, cc, uio); 
711 if (error != 0) 
712 return error; 
713 mutex_spin_enter(&tty_lock); 
714 /* check again for safety */ 
715 if (!ISSET(tp->t_state, TS_ISOPEN)) { 
716 /* 
717 * adjust for data copied in but not 
718 * written 
719 */ 
720 uio->uio_resid += cc; 
721 error = EIO; 
722 goto out; 
723 } 
724 } 
725 if (cc) 
726 (void) b_to_q(cp, cc, &tp->t_canq); 
727 cc = 0; 
728 } 
729 (void) putc(0, &tp->t_canq); 
730 ttwakeup(tp); 
731 cv_broadcast(&tp->t_cancv); 
732 error = 0; 
733 goto out; 
734 } 
735 while (uio->uio_resid > 0) { 
736 if (cc == 0) { 
737 cc = min(uio->uio_resid, BUFSIZ); 705 cc = min(uio->uio_resid, BUFSIZ);
 706 cc = min(cc, TTYHOG - tp->t_canq.c_cc);
738 cp = locbuf; 707 cp = locbuf;
739 mutex_spin_exit(&tty_lock); 708 mutex_spin_exit(&tty_lock);
740 error = uiomove((void *)cp, cc, uio); 709 error = uiomove(cp, cc, uio);
741 if (error != 0) 710 if (error != 0)
742 return error; 711 return error;
743 mutex_spin_enter(&tty_lock); 712 mutex_spin_enter(&tty_lock);
744 /* check again for safety */ 713 /* check again for safety */
745 if (!ISSET(tp->t_state, TS_ISOPEN)) { 714 if (!ISSET(tp->t_state, TS_ISOPEN)) {
746 /* adjust for data copied in but not written */ 715 /*
 716 * adjust for data copied in but not
 717 * written
 718 */
747 uio->uio_resid += cc; 719 uio->uio_resid += cc;
748 error = EIO; 720 error = EIO;
749 goto out; 721 goto out;
750 } 722 }
 723 if (cc) {
 724 cc = b_to_q(cp, cc, &tp->t_outq);
 725 if (cc > 0)
 726 goto block;
 727 }
 728 }
 729 (void) putc(0, &tp->t_canq);
 730 ttwakeup(tp);
 731 cv_broadcast(&tp->t_cancv);
 732 error = 0;
 733 goto out;
 734 }
 735 while (uio->uio_resid > 0) {
 736 cc = min(uio->uio_resid, BUFSIZ);
 737 cp = locbuf;
 738 mutex_spin_exit(&tty_lock);
 739 error = uiomove(cp, cc, uio);
 740 if (error != 0)
 741 return error;
 742 mutex_spin_enter(&tty_lock);
 743 /* check again for safety */
 744 if (!ISSET(tp->t_state, TS_ISOPEN)) {
 745 /* adjust for data copied in but not written */
 746 uio->uio_resid += cc;
 747 error = EIO;
 748 goto out;
751 } 749 }
752 while (cc > 0) { 750 while (cc > 0) {
753 if ((tp->t_rawq.c_cc + tp->t_canq.c_cc) >= TTYHOG - 2 && 751 int used = tp->t_rawq.c_cc + tp->t_canq.c_cc;
754 (tp->t_canq.c_cc > 0 || !ISSET(tp->t_lflag, ICANON))) { 752 int canon = ISSET(tp->t_lflag, ICANON) ? 1 : 0;
 753 /*
 754 * We need space for 2 characters if canonical
 755 * because we might need to print ^C
 756 */
 757 if (used >= (TTYHOG - canon) &&
 758 (tp->t_canq.c_cc > 0 || !canon)) {
755 cv_broadcast(&tp->t_rawcv); 759 cv_broadcast(&tp->t_rawcv);
756 goto block; 760 goto block;
757 } 761 }
758 /* XXX - should change l_rint to be called with lock 762 /*
 763 * XXX - should change l_rint to be called with lock
759 * see also tty.c:ttyinput_wlock() 764 * see also tty.c:ttyinput_wlock()
760 */ 765 */
761 mutex_spin_exit(&tty_lock); 766 mutex_spin_exit(&tty_lock);
762 (*tp->t_linesw->l_rint)(*cp++, tp); 767 (*tp->t_linesw->l_rint)(*cp++, tp);
763 mutex_spin_enter(&tty_lock); 768 mutex_spin_enter(&tty_lock);
764 cnt++; 769 cnt++;
765 cc--; 770 cc--;
766 } 771 }
767 cc = 0; 
768 } 772 }
769 error = 0; 773 error = 0;
770 goto out; 774 goto out;
771 775
772block: 776block:
773 /* 777 /*
774 * Come here to wait for slave to open, for space 778 * Come here to wait for slave to open, for space
775 * in outq, or space in rawq. 779 * in outq, or space in rawq.
776 */ 780 */
777 if (!ISSET(tp->t_state, TS_CARR_ON)) { 781 if (!ISSET(tp->t_state, TS_CARR_ON)) {
778 /* adjust for data copied in but not written */ 782 /* adjust for data copied in but not written */
779 uio->uio_resid += cc; 783 uio->uio_resid += cc;
780 error = EIO; 784 error = EIO;