bill@unixland.uucp (Bill Heiser) (03/05/91)
I have a user that wants to get a list of hosts on the network that respond with n seconds. I have a "timeout" program that someone on the net sent me -- it times out if a command doesn't complete within a certain number of seconds -- and aborts the command. Anyway, he is trying to do something like timeout 10 rup > rup.list When the timeout occurs, though, there is nothing in rup.list! The same thing happens if I type 'rup > rup.lis' and control-c out of it after some time period. Is it something to do with buffering of output? How can I make whatever output occurs within seconds go to the file? Thanks! -- home: ...!{uunet,bloom-beacon,esegue}!world!unixland!bill bill@unixland.uucp The Think_Tank BBS & Public Access Unix 508-655-3848 (2400) 508-651-8723 (9600-HST) 508-651-8733 (9600-PEP-V32) other: heiser@world.std.com
tchrist@convex.COM (Tom Christiansen) (03/05/91)
From the keyboard of bill@unixland.uucp (Bill Heiser): :I have a user that wants to get a list of hosts on the network :that respond with n seconds. I have a "timeout" program that someone :on the net sent me -- it times out if a command doesn't complete :within a certain number of seconds -- and aborts the command. [possibly mine -- i've one that looks like that i've sent out] :Anyway, he is trying to do something like : timeout 10 rup > rup.list : :When the timeout occurs, though, there is nothing in rup.list! : :The same thing happens if I type 'rup > rup.lis' and control-c :out of it after some time period. : :Is it something to do with buffering of output? Yes, that's exactly it. Stdio is disk buffering. :How can I make whatever output occurs within seconds go to the file? You need to get it to think its output is a tty. Dan will suggest using pty. Nothing much short of hacking the source comes to mind. While it's nice that pty should care of a lot of obnoxious things like this, I think that this is just a hack around a problem caused by lack of design forethought in stdio: you shouldn't need a whole pty just to get line buffering! --tom
libes@cme.nist.gov (Don Libes) (03/06/91)
In article <1991Mar05.080251.15424@convex.com> tchrist@convex.COM (Tom Christiansen) writes: >: he is trying to do something like >: timeout 10 rup > rup.list >:When the timeout occurs, though, there is nothing in rup.list! >You need to get it to think its output is a tty. Dan will suggest >using pty. Nothing much short of hacking the source comes to mind. You can do this with expect. Here is a csh alias that allows your original "timeout ..." command to work correctly. alias timeout 'expect -c "set timeout \!:1; spawn \!:2; expect"' >While it's nice that pty should care of a lot of obnoxious things like >this, I think that this is just a hack around a problem caused by lack >of design forethought in stdio: you shouldn't need a whole pty just to >get line buffering! I agree. Don Libes libes@cme.nist.gov ...!uunet!cme-durer!libes
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (03/06/91)
In article <1991Mar05.080251.15424@convex.com> tchrist@convex.COM (Tom Christiansen) writes: > You need to get it to think its output is a tty. Dan will > suggest using pty. Yep, like % timeout 10 pty rup > rup.list. > While it's nice that pty should care of a lot of > obnoxious things like this, I think that this is just a hack > around a problem caused by lack of design forethought in stdio: > you shouldn't need a whole pty just to get line buffering! Agreed. This brings up a general question: How should the system have been organized in the first place to avoid such problems? People often suggest an environment variable to control stdio buffering, but this doesn't seem like enough to me. I don't think stdio should even do the initial stat(), or provide isatty(). Do new users really expect ls or more to behave differently inside a pipe? Does any program really benefit from buffering differently when it writes to a file? I doubt it. ---Dan
kpv@ulysses.att.com (Phong Vo[drew]) (03/07/91)
In article <6580:Mar605:00:5591@kramden.acf.nyu.edu>, brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
: > you shouldn't need a whole pty just to get line buffering!
:
: Agreed. This brings up a general question: How should the system have
: been organized in the first place to avoid such problems? People often
A simple rule that takes care of many of the common complains with buffering
is to turn on line buffering for any case that implies interaction
with a different active process, e.g., a pipe or a person with a tty.
: suggest an environment variable to control stdio buffering, but this
: doesn't seem like enough to me. I don't think stdio should even do the
: initial stat(), or provide isatty().
The above rule would eliminate the need for isatty().
The stat is still useful because it contains information that the library
can use to tune its buffering strategy. For example, if a file is opened
to read and it has only a few hundred bytes, the library should not allocate
a full page buffer. On systems with memory mapping, if a stream has the
appropriate attributes, the library may even try to memory map instead
of read/write with buffers.
:Do new users really expect ls or
: more to behave differently inside a pipe?
Users probably don't care one way or the other as long as things work.
The crux of the matter is really that the notion of
lines of text is ingrained in many common UNIX programs. They expect
to process a line at a time. Therefore, in any "interactive" situation,
they expect streams to be line-buffered. When this is not
the case, programs get stuck and users get annoyed.
:Does any program really
: benefit from buffering differently when it writes to a file? I doubt it.
:
If you care about efficiency, then, sure, different schemes for buffering
can make a big difference.