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

From: Pádraig Brady <[email-masked]>
Date: Thu, 30 Jun 2011 12:15:03 +0100

On 30/06/11 00:42, Bruno Haible wrote:
> Pádraig Brady wrote:
>> The following shows I think that iconv is bypassing stdio and buffering internally?
>>
>> (echo; sleep 3; echo) | ltrace iconv -f ASCII
> 
> This is true for the glibc 'iconv' program. But stdbuf also does not work with
> 'iconv' from GNU libiconv, and this program uses stdio in a very simple form:
> It reads from stdin using fread(). It does *not* call setvbuf explicitly.
> 
> $ (echo; sleep 3; echo) | ltrace iconv -f ASCII

> fread(0xffe1f110, 1, 4096, 0xf7df5420)                                                           = 2

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

>From stdbuf.c /* FIXME: Should we mandate at least one option?  */

Anway I don't think that this works even if you specify -i0
because fread() only seems to return after feof() or ferror()
as demonstrated by interacting with the following run with ltrace.

#include <stdio.h>
int main(void)
{
    setvbuf (stdin, NULL, _IONBF, 0);
    setvbuf (stdout, NULL, _IONBF, 0);
    char buf[BUFSIZ];
    for (;;) {
      size_t count = fread (buf,1,BUFSIZ,stdin);
      fwrite (buf,1,count,stdin);
      if (feof (stdin))
        break;
    }
    return 0;
}

I guess glibc could return early if there were no partial records
(which there never will be with a size of 1).
It's a bit surprising it doesn't even given the
wording of the man page.

cheers,
Pádraig.