Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 23 Oct 2012 23:39:28 +0300
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        Jeremy Chadwick <jdc@koitsu.org>
Cc:        ed@freebsd.org, freebsd-stable@freebsd.org, jhb@freebsd.org
Subject:   Re: pty/tty or signal strangeness, or grep/bsdgrep bug?
Message-ID:  <20121023203928.GZ35915@deviant.kiev.zoral.com.ua>
In-Reply-To: <20121023142703.GA79098@icarus.home.lan>
References:  <20121023142703.GA79098@icarus.home.lan>

next in thread | previous in thread | raw e-mail | index | archive | help

--vF5oyOIHWRbsqp7A
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

On Tue, Oct 23, 2012 at 07:27:03AM -0700, Jeremy Chadwick wrote:
> Please keep me CC'd as I'm not subscribed to the list.
>=20
> Something "fun" today.  First off: yes, I should have been using
> 'bsdgrep -r -- "-2011" .', and yes that works fine, but that's besides
> the point.  Here we go:
>=20
> % bsdgrep -r "-2011" .
> ^Z
> Suspended
> % bg
> [1]    bsdgrep -r -2011 . &
> % qqqqqqqqqqq
> %
> % fg(standard input):qqqqqqqqqfgfg
>=20
> bsdgrep -r -2011 .
> ^C
> %
>=20
> Let me explain what transpired from an input perspective:
>=20
> 1. Ran bsdgrep -r "-2011" .
> 2. Pressed Ctrl-Z
> 3. Typed bg
> 4. Typed "q" 20 times in a row exactly
> 5. Pressed Ctrl-C
> 6. Typed "fg" and pressed Enter
> 7. Typed "ffgg" and pressed Enter
> 8. Pressed Ctrl-Z and Enter
> 9. Pressed Ctrl-C
>=20
> What's going on here?  Where is the famous "Suspended (tty input)"?  It
> gets more interesting.  Here's another one:
>=20
> % bsdgrep -r "-2011" .
> ^Z
> Suspended
> % bg
> [1]    bsdgrep -r -2011 . &
> % g(standard input):f
> fg
> gfg: Command not found.
> [1]  + Suspended (tty input)         bsdgrep -r -2011 .
> % jobs
> [1]  + Suspended (tty input)         bsdgrep -r -2011 .
> % fg
> bsdgrep -r -2011 .
> %
>=20
> And what transpired input-wise:
>=20
> 1. Ran bsdgrep -r "-2011" .
> 2. Pressed Ctrl-Z
> 3. Typed bg
> 4. Typed "fg" and Enter
> 5. Typed "fg" again and pressed Enter
> 6. Typed "jobs" and pressed Enter
> 7. Typed "fg" and pressed Enter
> 8. Pressed Ctrl-D
>=20
> Some facts:
>=20
> - Fully 100% reproducible
> - Tested only on RELENG_9 (source from 2012/10/21)
> - Happens regardless of shell (bash and csh tested; csh w/out dot files)
> - Similar behaviour happens with our base system grep (GNU grep) but
>   sometimes it manifests itself in a weirder way
> - bsdgrep and GNU grep are both in state "ttyin" when this happens
>=20
> CC'ing some folks who might have some ideas or can explain how to
> troubleshoot this one.  For the signal part, I believe this would be
> SIGTTIN.

This is reproducable with the cat(1) as well. The telling part is that
the backgrounded process stays on the "ttyin" cv. The code for e.g.
tty read currently is structured as follows:
	check for background process reading from CTTY, send SIGTTYIN
	loop {
		sleep waiting for input
		process input
	}
The problem is that the SIGCONT does not remove the sleeping process from
the sleep queue, so the sleep is not interrupted with error. Instead, the
process is woken up later when input is available.

Old tty code did the recheck for background state inside the loop after
the sleep.

Below is the hacky change that seemingly helped for exactly your case.
New code is structured so that the fix requires big movements of blocks,
e.g. even if keeping my patch, the for (;;) loops in tty_ttydisc.c
no longer have any use.

Hope Ed will comment.

diff --git a/sys/kern/tty.c b/sys/kern/tty.c
index e9c0fb6..3785e81 100644
--- a/sys/kern/tty.c
+++ b/sys/kern/tty.c
@@ -434,6 +434,7 @@ ttydev_read(struct cdev *dev, struct uio *uio, int iofl=
ag)
 	if (error)
 		goto done;
=20
+check_bg:
 	error =3D tty_wait_background(tp, curthread, SIGTTIN);
 	if (error) {
 		tty_unlock(tp);
@@ -441,6 +442,8 @@ ttydev_read(struct cdev *dev, struct uio *uio, int iofl=
ag)
 	}
=20
 	error =3D ttydisc_read(tp, uio, ioflag);
+	if (error =3D=3D EJUSTRETURN)
+		goto check_bg;
 	tty_unlock(tp);
=20
 	/*
@@ -462,6 +465,7 @@ ttydev_write(struct cdev *dev, struct uio *uio, int iof=
lag)
 	if (error)
 		return (error);
=20
+check_bg:
 	if (tp->t_termios.c_lflag & TOSTOP) {
 		error =3D tty_wait_background(tp, curthread, SIGTTOU);
 		if (error)
@@ -484,6 +488,8 @@ ttydev_write(struct cdev *dev, struct uio *uio, int iof=
lag)
 		tp->t_flags &=3D ~TF_BUSY_OUT;
 		cv_signal(&tp->t_outserwait);
 	}
+	if (error =3D=3D EJUSTRETURN)
+		goto check_bg;
=20
 done:	tty_unlock(tp);
 	return (error);
diff --git a/sys/kern/tty_ttydisc.c b/sys/kern/tty_ttydisc.c
index 52a5df2..d8b8f53 100644
--- a/sys/kern/tty_ttydisc.c
+++ b/sys/kern/tty_ttydisc.c
@@ -157,7 +157,7 @@ ttydisc_read_canonical(struct tty *tp, struct uio *uio,=
 int ioflag)
 			error =3D tty_wait(tp, &tp->t_inwait);
 			if (error)
 				return (error);
-			continue;
+			return (EJUSTRETURN);
 		}
=20
 		/* Don't send the EOF char back to userspace. */
@@ -208,6 +208,7 @@ ttydisc_read_raw_no_timer(struct tty *tp, struct uio *u=
io, int ioflag)
 		error =3D tty_wait(tp, &tp->t_inwait);
 		if (error)
 			return (error);
+		return (EJUSTRETURN);
 	}
 }
=20
@@ -256,6 +257,7 @@ ttydisc_read_raw_read_timer(struct tty *tp, struct uio =
*uio, int ioflag,
 		error =3D tty_timedwait(tp, &tp->t_inwait, hz);
 		if (error)
 			return (error =3D=3D EWOULDBLOCK ? 0 : error);
+		return (EJUSTRETURN);
 	}
=20
 	return (0);
@@ -301,6 +303,7 @@ ttydisc_read_raw_interbyte_timer(struct tty *tp, struct=
 uio *uio, int ioflag)
 		error =3D tty_wait(tp, &tp->t_inwait);
 		if (error)
 			return (error);
+		return (EJUSTRETURN);
 	}
=20
 	return ttydisc_read_raw_read_timer(tp, uio, ioflag, oresid);
@@ -539,6 +542,9 @@ ttydisc_write(struct tty *tp, struct uio *uio, int iofl=
ag)
 				error =3D EIO;
 				goto done;
 			}
+
+			error =3D EJUSTRETURN;
+			goto done;
 		} while (oblen > 0);
 	}
=20

--vF5oyOIHWRbsqp7A
Content-Type: application/pgp-signature

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.12 (FreeBSD)

iEYEARECAAYFAlCHAIAACgkQC3+MBN1Mb4jhPQCg2DoFg/SNC9ztV1XujxdlThpy
IK0AoLjFEDVKMpv87BKNDPxrSKHw8jmn
=YBtk
-----END PGP SIGNATURE-----

--vF5oyOIHWRbsqp7A--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20121023203928.GZ35915>