How to check the buffer type of an output stream?

Viewed 430

Using setvbuf(), we can change the buffer type of a FILE* stream to one of:

  • _IONBF (unbuffered)
  • _IOLBF (line buffered)
  • _IOFBF (fully buffered)

For example, in order to set stderr to line buffered, we could do the following:

setvbuf(stderr, NULL, _IOLBF, 0);

Is there also a way to figure out the current buffer type for a given output stream (using a file descriptor or FILE pointer)?

1 Answers

It's not possible. There is no standard way of determining the current buffering characteristic of a opened FILE.

There are non standard functions introduced by Solaris available in GNU C library, there is __flbf function in stdio_ext.h in GNU C library, that returns nonzero value in case the stream is line buffered.

After inspecting glibc sources libio/iosetvbuf.c the following program that you shouldn't use seems to work on my platform with GNU libc 2.31:

#include <stdio.h>

#ifdef __GLIBC__
#define _IO_UNBUFFERED        0x0002
#define _IO_LINE_BUF          0x0200
int getvbuf(FILE *f) {
    if (f->_flags & _IO_UNBUFFERED) {
        return _IONBF;
    } else if (f->_flags & _IO_LINE_BUF) {
        return _IOLBF;
    }
    return _IOFBF;
}
#else
#error This program works only with glibc.
#endif

const char *vbuf_to_str(int a) {
    switch (a) {
    case _IONBF: return "_IONBF";
    case _IOLBF: return "_IOLBF";
    case _IOFBF: return "_IOFBF";
    }
    return "unknown";
}

int main() {
    setvbuf(stderr, NULL, _IONBF, 0);
    printf("%s\n", vbuf_to_str(getvbuf(stderr)));
    setvbuf(stderr, NULL, _IOLBF, 0);
    printf("%s\n", vbuf_to_str(getvbuf(stderr)));
    setvbuf(stderr, NULL, _IOFBF, 0);
    printf("%s\n", vbuf_to_str(getvbuf(stderr)));
}
Related