Buffering of C streams

This topic describes buffering modes used by z/OS® XL C/C++ library functions available to control buffering and methods of flushing buffers.

z/OS XL C/C++ uses buffers to map C I/O to system-level I/O. When z/OS XL C/C++ performs I/O operations, it uses one of the following buffering modes:
  • Line buffering - characters are transmitted to the system as a block when a new-line character is encountered. Line buffering is meaningful only for text streams and UNIX file system files.
  • Full buffering - characters are transmitted to the system as a block when a buffer is filled.
  • No buffering - characters are transmitted to the system as they are written. Only regular memory files and UNIX file system files support the no buffering mode.
The buffer mode affects the way the buffer is flushed. You can use the setvbuf() and setbuf() library functions to control buffering, but you cannot change the buffering mode after an I/O operation has used the buffer, as all read, write, and reposition operations do. In some circumstances, repositioning alters the contents of the buffer. It is strongly recommended that you only use setbuf() and setvbuf() before any I/O, to conform with ANSI, and to avoid any dependency on the current implementation. If you use setvbuf(), z/OS XL C/C++ may or may not accept your buffer for its internal use. For a hiperspace memory file, if the size of the buffer specified to setvbuf() is 8K or more, it will affect the number of hiperspace blocks read or written on each call to the operating system; the size is rounded down to the nearest multiple of 4K.
Full buffering is the default except in the following cases:
  • If you are using an interactive terminal, z/OS XL C/C++ uses line buffering.
  • If you are running under CICS®, z/OS XL C/C++ also uses line buffering.
  • stderr is line-buffered by default.
  • If you are using a memory file, z/OS XL C/C++ does not use any buffering.
For terminals, because I/O is always unblocked, line buffering is equivalent to full buffering.

For record I/O files, buffering is meaningful only for blocked files or for record I/O files in z/OS UNIX file system using full buffering. For unblocked files, the buffer is full after every write and is therefore written immediately, leaving nothing to flush. For blocked files or fully-buffered UNIX file system files, however, the buffer can contain one or more records that have not been flushed and that require a flush operation for them to go to the system.

For blocked I/O files, buffering is always meaningless.

You can flush buffers to the system in several different ways.
  • If you are using full buffering, z/OS XL C/C++ automatically flushes a buffer when it is filled.
  • If you are using line buffering for a text file or a UNIX file system file, z/OS XL C/C++ flushes a buffer when you complete it with a control character. Except for UNIX file system files, specifying line buffering for a record I/O, blocked I/O, or binary file has no effect; z/OS XL C/C++ treats the file as if you had specified full buffering.
  • z/OS XL C/C++ flushes buffers to the system when you close a file or end a program.
  • z/OS XL C/C++ flushes buffers to the system when you call the fflush() library function, with the following restrictions:
    • A file opened in text mode does not flush data if a record has not been completed with a new-line.
    • A file opened in fixed format does not flush incomplete records to the file.
    • An FBS file does not flush out a short block unless it is a DISK file opened without the NOSEEK parameter.
  • All streams are flushed across non-POSIX system() calls. Streams are not flushed across POSIX system() calls. For a POSIX system call, we recommend that you do a fflush() before the system() call.
Note: This is not supported for VSAM files.

You may not see output if a program that is using input and output fails, and the error handling routines cannot close all the open files.