Ping puzzle
John Chambers
jc at trillian.mit.edu
Wed Mar 26 22:21:13 EST 2003
Kevin D. Clark comments:
| So, FreeBSD's stdio layer is different from Linux's.
Probably, but I don't think that's what's happening here. Pretty much
all stdios buffer stdout but not stderr by default. But a program can
call setbuf() or setlinebuf() or fflush(). I'd guess that the
problematic pings are leaving stdout buffered and calling fflush()
only for "good" ICMP replies but not for failures.
| > The guess that they're being buffered is likely correct.
| I wasn't really guessing... (-:
Thought not. That was my main conjecture, too, despite the strange
way it's being done. So how to undo it? Some programs have explicit
options to cause unbuffered (or line buffered) output. There isn't
one documented for ping, but that doesn't mean it doesn't exist.
| > Maybe if I waited long enough, the parent would get those messages.
| Yes.
Possibly, but some of my tests have run for hours (until the ping
gives up), and the parent never sees the messages.
| How long does it take for you to see any output when you do this?:
|
| perl -le 'print(i++), sleep(1) while(1);' | more
Well, that gets an instantaneous reply, a syntax error message. So I
inserted the missing $ and it hung. About two hours later the output
started to appear. Not encouraging.
| Convince ping's stdio that it is connected to a terminal. IIRC,
| there's a program in the expect distribution ("unbuffer"?) that does
| exactly this.
Funny thing: I have an expect that I used on a project a couple of
years ago, and find couldn't find any "unbuffer*" files. I looked
around on a bunch of machines, including some RH 7.2 and 8.0 systems,
and none of them had expect or unbuffer. Then I found it on one of my
home machines that's still running RH 6.2. /usr/bin/unbuffer is four
years old (older than my expect source), but it works. Maybe I should
grab a new expect and install the latest version. Maybe I should grab
a new tcl/tk, too. At the moment, it's very handy that I've left that
one machine at RH 6.2, though. But it may be a 9.0 system soon ...
Funny thing about finding this old unbuffer: I copied it around to a
bunch of other machines, several linices, FreeBSDs and OpenBSDs on
Intel hardware, and the binary worked on all of them. So much for the
supposed competition and enmity between these crowds. I think that's
mostly for show, since it's pretty obvious that behind the scenes
they're sharing each others' code fairly extensively. No surprise, I
suppose; each gang has a lot of pragmatic and intelligent people. If
it's Open Source, why not use it?
| > I wonder if there's a perl ping module? ;-)
|
| Yes there is, but the last time I worked with this module, I recall
| that it used the TCP echo port to determine "ping" status -- not
| ICMP -- although I recall that you could get it to use ICMP if you
| leapt through some hoops.
It would also have the problem with ICMP that it wouldn't work on a
machine where I don't have root access. But maybe I should take a
look at it. If I could do the job from my perl programs, it would
eliminate the need for an "unbuffer ping ..." pipeline.
| I've written my own version of ping for various projects I've worked
| on in the past; I understand your concerns about doing this. I think
| that if you want this functionality, you're going to have to pick your
| poison...
I've hacked a number of pings. I'd agree with you. It ain't pretty.
The really ugly part, though, is the way that different vendors make
so many changes to ping, so that you can't write a portable script
that calls it.
One fun thing that I did once that was really useful: I hacked the
ping to run in "pipe" mode, where it accepted hosts (names or
addresses) on stdin, pinged them all, and wrote to stdout whenever it
got a reply. This could be used as a subprocess from a parent that
wants to ping a lot of hosts, and it only needs to start one
subprocess. Maybe I should hack the linux ping to work this way. Now
that linux is taking over the world, I may not need to do it on other
kinds of machines in the future ...
The "unbuffer ping ..." approach produces two processes per pinged
host. For your typical net monitoring package (which is what I'm
working on), you often have lots of host icons in the pretty picture,
and this produces a twice as many subprocesses. It works, but it's
not pretty (or efficient). But I guess it's better than firing up a
new ping process per host every N seconds.
More information about the Discuss
mailing list