C Programming/stdio.h/setvbuf

setvbuf is a function in standard C which lets the programmer control the buffering of a file stream. It is declared in <stdio.h>; its function prototype is:

int setvbuf(FILE *stream, char *buf, int mode, size_t size);

The stream argument is a pointer to the file stream for which the relevant buffering operations will be performed; buf is a character array of size in length, or a null pointer; and mode is the kind of buffering desired: _IOFBF, for fully buffered, _IOLBF for line buffered and _IONBF for unbuffered. These three macros are defined in <stdio.h>. setvbuf returns zero on success or nonzero on failure.

If buf is a null pointer, the system will dynamically allocate a buffer of the specified size (size characters). If mode is _IONBF, the stream I/O will not be buffered, causing each subsequent I/O operation on the stream to be performed immediately, and the buf and size arguments are ignored.

A related function, setbuf also controls the buffering of a file stream. Unlike setvbuf, setbuf takes only two arguments. The prototype is:

void setbuf(FILE *stream, char *buf);

setbuf's behavior is equivalent to:

(void)setvbuf(stream, buf, buf ? _IOFBF : _IONBF, BUFSIZ);

That is, if buf is not NULL, set the stream to fully buffered using the given buffer; otherwise, set the stream to unbuffered. If a buffer is provided to setbuf, it must be at least BUFSIZ bytes long. The function always succeeds.

The code below is very unstable and might not work properly on specific compilers. It may even buffer overflow.. C99 says that setvbuf may not be called after writing to the stream, so this code invokes undefined behavior. C99 footnote 230 (non-normative) says the stream should be closed before buf is deallocated at the end of main.

Example

edit

The output of this program should be Hello world followed by a newline. Note this example is broken as it implements what the manpage clearly labels as a bug: The buffer needs to be still there when the stream is closed. Here, the buffer goes away upon leaving main, but the stream is closed only afterwards when the program terminates.

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

int main(void) {
    char buf[42];

    if(setvbuf(stdout, buf, _IOFBF, sizeof buf)) {
        perror("failed to change the buffer of stdout");
        return EXIT_FAILURE;
    }
    printf("He");
    /* The buffer contains "He"; nothing is written yet to stdout */
    fflush(stdout); /* "He" is actually written to stdout */

    if(setvbuf(stdout, NULL, _IONBF, 0)) {
        perror("failed to change the buffer of stdout");
        return EXIT_FAILURE;
    }
    printf("llo w"); /* "llo w" is written to stdout, there is no buffering */

    if(setvbuf(stdout, buf, _IOLBF, sizeof buf)) {
        perror("failed to change the buffer of stdout");
        return EXIT_FAILURE;
    }
    printf("orld"); /* The buffer now contains "orld"; nothing is written yet to stdout */
    putchar('\n'); /* stdout is line buffered; everything in the buffer is now written to stdout along with the newline */

    return EXIT_SUCCESS;
}
edit