Subject: bug#8961: stdbuf has no effect on some programs

From: Bruno Haible <[email-masked]>
Date: Thu, 30 Jun 2011 21:27:40 +0200

Hi Pádraig,

> > $ (echo Hello; sleep 3; echo World) | stdbuf iconv -f ASCII
> > Hello
> > World
> 
> From stdbuf.c /* FIXME: Should we mandate at least one option?  */

Oops, I meant this:

$ (echo Hello; sleep 3; echo World) | stdbuf -i 0 iconv -f ASCII
Hello
World

Here too, the output comes only at the end, all at once.

> Anway I don't think that this works even if you specify -i0
> because fread() only seems to return after feof() or ferror()

Exactly. So, on which kinds of programs can -i0 work?
  - Not in programs that use read(0,...) because they are not affected
    by LD_PRELOADs.
  - Not in programs that use fread().
  - Not in programs that use getc() repeatedly - because the buffering
    behaviour of stdio is independent of whether you use fread() or [f]getc().
Can you name a single program on which -i0 works?

> int main(void)
> {
>     setvbuf (stdin, NULL, _IONBF, 0);
>     setvbuf (stdout, NULL, _IONBF, 0);

But most program's _don't_ call setvbuf. If a program, like 'grep', has
an option like --line-buffered, then I don't need setvbuf.

> I'll might also add a note about fread() blocking (which POSIX requires)
> and that setting no _buffering_ doesn't impact that.

Yes, that seems to be the point. "no buffering" != "non-blocking".

Could 'stdbuf -i0' be changed to put file descriptor 0 into non-blocking state
before invoking the child process? Is that the solution?

Bruno
-- 
In memoriam Jürgen Ponto <http://en.wikipedia.org/wiki/Jürgen_Ponto>