From owner-svn-src-stable-9@FreeBSD.ORG Sun Nov 11 12:12:44 2012 Return-Path: Delivered-To: svn-src-stable-9@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id DE6C2CF5; Sun, 11 Nov 2012 12:12:44 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id C48DB8FC08; Sun, 11 Nov 2012 12:12:44 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id qABCCi1M081557; Sun, 11 Nov 2012 12:12:44 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id qABCCiHA081554; Sun, 11 Nov 2012 12:12:44 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <201211111212.qABCCiHA081554@svn.freebsd.org> From: Ed Schouten Date: Sun, 11 Nov 2012 12:12:44 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r242892 - in stable/9/sys: kern sys X-SVN-Group: stable-9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable-9@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: SVN commit messages for only the 9-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 11 Nov 2012 12:12:44 -0000 Author: ed Date: Sun Nov 11 12:12:44 2012 New Revision: 242892 URL: http://svnweb.freebsd.org/changeset/base/242892 Log: MFC r241161: Fix faulty error code handling in read(2) on TTYs. When performing a non-blocking read(2), on a TTY while no data is available, we should return EAGAIN. But if there's a modem disconnect, we should return 0. Right now we only return 0 when doing a blocking read, which is wrong. MFC r242078: Correct SIGTTIN handling. In the old TTY layer, SIGTTIN was correctly handled like this: while (data should be read) { send SIGTTIN if not foreground process group read data } In the new TTY layer, however, this behaviour was changed, based on a false interpretation of the standard: send SIGTTIN if not foreground process group while (data should be read) { read data } Correct this by pushing tty_wait_background() into the ttydisc_read_*() functions. Reported by: koitsu PR: kern/173010 Modified: stable/9/sys/kern/tty.c stable/9/sys/kern/tty_ttydisc.c stable/9/sys/sys/tty.h Directory Properties: stable/9/sys/ (props changed) Modified: stable/9/sys/kern/tty.c ============================================================================== --- stable/9/sys/kern/tty.c Sun Nov 11 12:06:12 2012 (r242891) +++ stable/9/sys/kern/tty.c Sun Nov 11 12:12:44 2012 (r242892) @@ -361,7 +361,7 @@ tty_is_ctty(struct tty *tp, struct proc return (p->p_session == tp->t_session && p->p_flag & P_CONTROLT); } -static int +int tty_wait_background(struct tty *tp, struct thread *td, int sig) { struct proc *p = td->td_proc; @@ -433,13 +433,6 @@ ttydev_read(struct cdev *dev, struct uio error = ttydev_enter(tp); if (error) goto done; - - error = tty_wait_background(tp, curthread, SIGTTIN); - if (error) { - tty_unlock(tp); - goto done; - } - error = ttydisc_read(tp, uio, ioflag); tty_unlock(tp); Modified: stable/9/sys/kern/tty_ttydisc.c ============================================================================== --- stable/9/sys/kern/tty_ttydisc.c Sun Nov 11 12:06:12 2012 (r242891) +++ stable/9/sys/kern/tty_ttydisc.c Sun Nov 11 12:12:44 2012 (r242892) @@ -126,6 +126,10 @@ ttydisc_read_canonical(struct tty *tp, s breakc[n] = '\0'; do { + error = tty_wait_background(tp, curthread, SIGTTIN); + if (error) + return (error); + /* * Quite a tricky case: unlike the old TTY * implementation, this implementation copies data back @@ -149,10 +153,10 @@ ttydisc_read_canonical(struct tty *tp, s /* No more data. */ if (clen == 0) { - if (ioflag & IO_NDELAY) - return (EWOULDBLOCK); - else if (tp->t_flags & TF_ZOMBIE) + if (tp->t_flags & TF_ZOMBIE) return (0); + else if (ioflag & IO_NDELAY) + return (EWOULDBLOCK); error = tty_wait(tp, &tp->t_inwait); if (error) @@ -192,6 +196,10 @@ ttydisc_read_raw_no_timer(struct tty *tp */ for (;;) { + error = tty_wait_background(tp, curthread, SIGTTIN); + if (error) + return (error); + error = ttyinq_read_uio(&tp->t_inq, tp, uio, uio->uio_resid, 0); if (error) @@ -200,10 +208,10 @@ ttydisc_read_raw_no_timer(struct tty *tp return (0); /* We have to wait for more. */ - if (ioflag & IO_NDELAY) - return (EWOULDBLOCK); - else if (tp->t_flags & TF_ZOMBIE) + if (tp->t_flags & TF_ZOMBIE) return (0); + else if (ioflag & IO_NDELAY) + return (EWOULDBLOCK); error = tty_wait(tp, &tp->t_inwait); if (error) @@ -229,6 +237,10 @@ ttydisc_read_raw_read_timer(struct tty * timevaladd(&end, &now); for (;;) { + error = tty_wait_background(tp, curthread, SIGTTIN); + if (error) + return (error); + error = ttyinq_read_uio(&tp->t_inq, tp, uio, uio->uio_resid, 0); if (error) @@ -248,10 +260,10 @@ ttydisc_read_raw_read_timer(struct tty * * We have to wait for more. If the timer expires, we * should return a 0-byte read. */ - if (ioflag & IO_NDELAY) - return (EWOULDBLOCK); - else if (tp->t_flags & TF_ZOMBIE) + if (tp->t_flags & TF_ZOMBIE) return (0); + else if (ioflag & IO_NDELAY) + return (EWOULDBLOCK); error = tty_timedwait(tp, &tp->t_inwait, hz); if (error) @@ -278,6 +290,10 @@ ttydisc_read_raw_interbyte_timer(struct */ for (;;) { + error = tty_wait_background(tp, curthread, SIGTTIN); + if (error) + return (error); + error = ttyinq_read_uio(&tp->t_inq, tp, uio, uio->uio_resid, 0); if (error) @@ -293,10 +309,10 @@ ttydisc_read_raw_interbyte_timer(struct break; /* We have to wait for more. */ - if (ioflag & IO_NDELAY) - return (EWOULDBLOCK); - else if (tp->t_flags & TF_ZOMBIE) + if (tp->t_flags & TF_ZOMBIE) return (0); + else if (ioflag & IO_NDELAY) + return (EWOULDBLOCK); error = tty_wait(tp, &tp->t_inwait); if (error) Modified: stable/9/sys/sys/tty.h ============================================================================== --- stable/9/sys/sys/tty.h Sun Nov 11 12:06:12 2012 (r242891) +++ stable/9/sys/sys/tty.h Sun Nov 11 12:12:44 2012 (r242892) @@ -180,6 +180,7 @@ void tty_signal_sessleader(struct tty *t void tty_signal_pgrp(struct tty *tp, int signal); /* Waking up readers/writers. */ int tty_wait(struct tty *tp, struct cv *cv); +int tty_wait_background(struct tty *tp, struct thread *td, int sig); int tty_timedwait(struct tty *tp, struct cv *cv, int timo); void tty_wakeup(struct tty *tp, int flags);