简体   繁体   中英

c setvbuf() function call not working as expected

I'm learning system programming and when I run the following code

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    char buff[5];
    setvbuf(stderr, buff, _IOFBF, 5);
    for (int i = 1; i < 10; i++) {
        fprintf(stderr, "%d", i);
    }
    _exit(0);
}

setvbuf is imposing fully buffered policy on stderr with a 5-byte sized buffer, so I expected to get 12345 but instead it prints 1234567 , why is that?

strace-ing the program shows that when compiled against glibc it first does a write of size 1, then a write of size 5, and finally a write of size 1:

$ strace -o /dev/stdout -e write,writev ./a.out 2>/dev/null
write(2, "1", 1)                        = 1
write(2, "23456", 5)                    = 5
write(2, "7", 1)                        = 1

With musl it does 7 writes of size 1:

$ strace -o /dev/stdout -e write,writev ./a.out 2>/dev/null
writev(2, [{iov_base="1", iov_len=1}, {iov_base=NULL, iov_len=0}], 2) = 1
writev(2, [{iov_base="2", iov_len=1}, {iov_base=NULL, iov_len=0}], 2) = 1
writev(2, [{iov_base="3", iov_len=1}, {iov_base=NULL, iov_len=0}], 2) = 1
writev(2, [{iov_base="4", iov_len=1}, {iov_base=NULL, iov_len=0}], 2) = 1
writev(2, [{iov_base="5", iov_len=1}, {iov_base=NULL, iov_len=0}], 2) = 1
writev(2, [{iov_base="6", iov_len=1}, {iov_base=NULL, iov_len=0}], 2) = 1
writev(2, [{iov_base="7", iov_len=1}, {iov_base=NULL, iov_len=0}], 2) = 1
writev(2, [{iov_base="8", iov_len=1}, {iov_base=NULL, iov_len=0}], 2) = 1
writev(2, [{iov_base="9", iov_len=1}, {iov_base=NULL, iov_len=0}], 2) = 1
+++ exited with 0 +++

So it's obvious that both C library implementations treat the size argument of setvbuf(stream, buf, _IOFBF, size) as a maximum, and they feel free to flush the buffer even before it's full.

AFAICS there doesn't seem to be anything in the standard against this interpretation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM