Subject: Re: /sbin/ping - fails to drop into background?
To: Lucio De Re <lucio@proxima.alt.za>
From: Geert Hendrickx <ghen@telenet.be>
List: tech-userlevel
Date: 08/03/2007 07:50:07
--8X7/QrJGcKSMr1RN
Content-Type: multipart/mixed; boundary="kXdP64Ggrk/fb43R"
Content-Disposition: inline


--kXdP64Ggrk/fb43R
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

On Thu, Aug 02, 2007 at 10:33:56PM -0700, John Nemeth wrote:
> On Dec 23,  1:32pm, Lucio De Re wrote:
> }
> } I only tried this with 1.6.1 and 2.1, but it sems that /sbin/ping
> } blocks if it is dropped into background, complaining about "tty
> } output" even when stdout and stderr are redirected on the command
> } line.  I see no option to turn this behaviour off and I need it so I
> } can use ping in a daemon script to establish connectivity.
>
>      It's been fixed for NetBSD 4.0.  You may be able to just grab the
> latest sources and try compiling and running it on an older release.

It has been fixed in rev 1.79 + 1.80 of src/sbin/ping (PR/33623), which
apply cleanly to NetBSD 2.x and 3.x (diff attached).  This could be pulled
up to netbsd-2 and netbsd-3...

	Geert

--kXdP64Ggrk/fb43R
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="ping.diff"
Content-Transfer-Encoding: quoted-printable

--- src/sbin/ping/ping.c	2006/05/09 20:18:08	1.78
+++ src/sbin/ping/ping.c	2006/06/01 18:04:08	1.80
@@ -241,7 +241,9 @@ static void jiggle(int), jiggle_flush(in
 static void gethost(const char *, const char *,
 		    struct sockaddr_in *, char *, int);
 static void usage(void);
-
+#if defined(SIGINFO) && defined(NOKERNINFO)
+static int fgtty(int, struct termios *);
+#endif
=20
 int
 main(int argc, char *argv[])
@@ -638,10 +640,10 @@ main(int argc, char *argv[])
 	(void)signal(SIGINT, prefinish);
=20
 #if defined(SIGINFO) && defined(NOKERNINFO)
-	if (tcgetattr (0, &ts) !=3D -1) {
+	if (fgtty(STDIN_FILENO, &ts) !=3D -1) {
 		reset_kerninfo =3D !(ts.c_lflag & NOKERNINFO);
 		ts.c_lflag |=3D NOKERNINFO;
-		tcsetattr (STDIN_FILENO, TCSANOW, &ts);
+		(void)tcsetattr(STDIN_FILENO, TCSANOW, &ts);
 	}
 #endif
=20
@@ -1340,6 +1342,22 @@ prefinish(int dummy)
 		npackets =3D ntransmitted;
 }
=20
+#if defined(SIGINFO) && defined(NOKERNINFO)
+static int
+fgtty(int fd, struct termios *ts)
+{
+	pid_t ttypgrp, pgrp;
+
+	if (tcgetattr(fd, ts) =3D=3D -1)
+		return -1;
+	if ((ttypgrp =3D tcgetpgrp(fd)) =3D=3D -1)
+		return -1;
+	if ((pgrp =3D getpgid(0)) =3D=3D -1)
+		return -1;
+
+	return ttypgrp =3D=3D pgrp ? 0 : -1;
+}
+#endif
=20
 /*
  * Print statistics and give up.
@@ -1351,9 +1369,16 @@ finish(int dummy)
 #if defined(SIGINFO) && defined(NOKERNINFO)
 	struct termios ts;
=20
-	if (reset_kerninfo && tcgetattr (0, &ts) !=3D -1) {
+	/*
+	 * Note that the following will suspend the ping program
+	 * if it is in the background. We could have used fgtty()
+	 * to avoid this, but then we would fail to restore the
+	 * tty setting. So we prefer to suspend here. XXX: NOKERNINFO
+	 * should prolly be a signal struct attribute
+	 */
+	if (reset_kerninfo && tcgetattr(STDIN_FILENO, &ts) !=3D -1) {
 		ts.c_lflag &=3D ~NOKERNINFO;
-		tcsetattr (STDIN_FILENO, TCSANOW, &ts);
+		(void)tcsetattr(STDIN_FILENO, TCSANOW, &ts);
 	}
 	(void)signal(SIGINFO, SIG_IGN);
 #else


--kXdP64Ggrk/fb43R--

--8X7/QrJGcKSMr1RN
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (NetBSD)

iQEVAwUBRrLCD4LS9urEu56fAQqo6Qf+NyMnPH6I+betkECDhujJerH9XC8nkCqb
ymwbDpYjBzOgd/FcsO0BaJLcXE9PSXbq/Fppz/rZkqFJwmpZsopR1If00NQqOx04
fNbrFialOqjQFbHKCX1DtPcDXmOSXHPF8VYp8Jkm2SgCZmjp2WN0FUPtoAZQymjN
PXGglx6DWvEuPhCriudXOG28e788FAZJcvuDPkvWPFhD4KFWEsoLfmkb2w8eXO7C
xC4HqDzZeU8VW2Igw3YNHiFbjvW+Ycwt+4SrACge6Y6EyuRz9InQMNprzpOhUB67
JtSU0SFeOeagpQZNtABlz4gFQfPWHDgdNqkalcUTuI+2RyFZuzODuA==
=svkA
-----END PGP SIGNATURE-----

--8X7/QrJGcKSMr1RN--