| @@ -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 | |
697 | again: | | 697 | again: |
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 | |
772 | block: | | 776 | block: |
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; |