Author: ed
Date: Thu Oct 25 09:05:21 2012
New Revision: 242078
URL: http://svn.freebsd.org/changeset/base/242078

Log:
  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
  MFC after:    2 weeks

Modified:
  head/sys/kern/tty.c
  head/sys/kern/tty_ttydisc.c
  head/sys/sys/tty.h

Modified: head/sys/kern/tty.c
==============================================================================
--- head/sys/kern/tty.c Thu Oct 25 09:02:21 2012        (r242077)
+++ head/sys/kern/tty.c Thu Oct 25 09:05:21 2012        (r242078)
@@ -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: head/sys/kern/tty_ttydisc.c
==============================================================================
--- head/sys/kern/tty_ttydisc.c Thu Oct 25 09:02:21 2012        (r242077)
+++ head/sys/kern/tty_ttydisc.c Thu Oct 25 09:05:21 2012        (r242078)
@@ -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
@@ -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)
@@ -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)
@@ -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)

Modified: head/sys/sys/tty.h
==============================================================================
--- head/sys/sys/tty.h  Thu Oct 25 09:02:21 2012        (r242077)
+++ head/sys/sys/tty.h  Thu Oct 25 09:05:21 2012        (r242078)
@@ -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);
 
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to