[comp.lang.c] When to use fflush

rac@sherpa.uucp (Roger A. Cornelius) (08/29/89)

When should you use fflush()? OR are there any guarantees of
when output buffers are flushed?  I have a program that uses
fputs() to print a prompt, then waits for a return to be typed.
The prompt is always displayed, but am I guaranteed of this?
Should I use fflush() anyway?  What's the rule for when to use
fflush(), and when it's not needed?

Thanks, Roger
--
Roger A. Cornelius           rac@sherpa            uunet!sherpa!rac

chris@mimsy.UUCP (Chris Torek) (08/30/89)

In article <143@sherpa.uucp> rac@sherpa.uucp (Roger A. Cornelius) writes:
>When should you use fflush()? OR are there any guarantees of
>when output buffers are flushed?

Output buffers are flushed by normal program exit (via exit() or
via return from main()), and, in the proposed C standard, by
`fflush((FILE *)NULL);'.  Some output buffers (those that are
`associated with terminals') are flushed by some kinds of input.

The short answer is:  Use fflush() whenever you want the output to
be visible.  Unfortunately, there is no way to simply declare that
all stdio buffers should always be fully buffered; the latter would
help efficiency, and help remind people to use fflush().
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

gwyn@smoke.BRL.MIL (Doug Gwyn) (08/31/89)

In article <143@sherpa.uucp> rac@sherpa.uucp (Roger A. Cornelius) writes:
>When should you use fflush()? OR are there any guarantees of
>when output buffers are flushed?

Use fflush() whenever you want to make sure that the buffers are forced out.

>I have a program that uses fputs() to print a prompt, then waits for a
>return to be typed.  The prompt is always displayed, but am I guaranteed
>of this?

Recent versions of stdio attempt to force out all output possibly associated
with a "terminal" whenever input is requested from a "terminal".  It is not
always possible to tell what is really a terminal, though.  Modern stdio
also defaults to line-buffered output on "terminals", although that wouldn't
help for a prompt on the same line as the input.

>Should I use fflush() anyway?  What's the rule for when to use
>fflush(), and when it's not needed?

See my first sentence.

paulb@ttidca.TTI.COM (Paul Blumstein) (09/01/89)

In article <19319@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes:
+Output buffers are flushed by normal program exit (via exit() or
+via return from main()), and, in the proposed C standard, by
+`fflush((FILE *)NULL);'.  Some output buffers (those that are
+`associated with terminals') are flushed by some kinds of input.

And don't forget the the buffers are also flushed by fclose() .
=============================================================================
Paul Blumstein       |          Carpe diem: Eat a carp today!
Citicorp/TTI         |
Santa Monica, CA     +-------------------------------------------------------
{philabs,csun,psivax}!ttidca!paulb  or  paulb@ttidca.TTI.COM
DISCLAIMER: Everything & everyone is hereby disclaimed!

karl@haddock.ima.isc.com (Karl Heuer) (09/02/89)

In article <10882@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes:
>Use fflush() whenever you want to make sure that the buffers are forced out.

I've forgotten whether this issue was ever resolved: what should happen if the
output stream is a VMS record-oriented file?  If the currently buffered output
contains no newlines, is it appropriate for fflush() to do nothing, and return
success?

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
(The problem is that, if I'm not mistaken, a `line' in such a file consists of
a record with a byte-count prefix, and no actual newline character.)

gwyn@smoke.BRL.MIL (Doug Gwyn) (09/03/89)

In article <14507@haddock.ima.isc.com> karl@haddock.ima.isc.com (Karl Heuer) writes:
>I've forgotten whether this issue was ever resolved: what should happen if the
>output stream is a VMS record-oriented file?  If the currently buffered output
>contains no newlines, is it appropriate for fflush() to do nothing, and return
>success?

The specification says that unwritten data IS delivered to the host
environment.  It does not (and cannot) be specific about how that is
actually accomplished.  Section 4.9.3 of the pANS describes buffering
matters using the phrase "intended to", in acknowledgement of the
fact that host environments vary widely in this regard.

I would think that so long as the implementation ensures that the
data will reach the record-structured file SOMEtime, that would
suffice.  Certainly on a terminal, though, the flush should cause
the unwritten characters to immediately be sent to the terminal.

scs@hstbme.mit.edu (Steve Summit) (09/17/89)

In article <14507@haddock.ima.isc.com> karl@haddock.ima.isc.com (Karl Heuer) writes:
>I've forgotten whether this issue was ever resolved: what should happen if the
>output stream is a VMS record-oriented file?  If the currently buffered output
>contains no newlines, is it appropriate for fflush() to do nothing, and return
>success?

In article <10913@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes:
>The specification says that unwritten data IS delivered to the host
>environment.  It does not (and cannot) be specific about how that is
>actually accomplished.
>I would think that so long as the implementation ensures that the
>data will reach the record-structured file SOMEtime, that would
>suffice.

Before the distinction between pANS C and Posix was as clear as
it is today, and before the exhortation to use stdio rather than
system calls in portable code was as strong, it was common to
provide open/read/write/etc. in a "foreign" (non-Unix) C RTL.  In
that case, the right place to handle newline-to-record-structure
conversion is of course in the write(2) emulation, not in stdio.
Indeed, using a VMS C RTL I once wrote, the stdio sources could
be taken from a Unix machine and compiled, without essential
change, to run successfully "on top of" the Unix system call
emulation.

In this situation, the mind-set when considering the stdio code
is that the underlying open/read/write emulation is "the
operating system" even though it is actually library code running
in user mode.  fflush's job is done when it has called write().
(The data has been "delivered to the host environment.")  The
fact that the characters which have been written are waiting in a
buffer at the write() level (waiting for the line to be
terminated or the file closed) and have not, in fact, been
written to the disk, is fairly equivalent to the fact that Unix
uses delayed writes and the same thing is essentially true after
a write(2) there.  (The buffering is merely happening one level
further up, or two levels if you consider that an emulation on
VMS is properly written on top of RMS which may impose its own
level of buffering before the VMS equivalent of low-level I/O
system calls are reached.)

A more interesting question (under this scheme) would be what
should happen if fflush() (or any code, for that matter) were to
call fsync() for a record-oriented text file.  I don't remember
if I implemented fsync() and, if I did, if I asked or answered
the premature record termination question.  A quality emulation
of fsync semantics would certainly force data to be written as
close to the disk as possible (calling RMS and lower-level flush
operations as appropriate).  It is probably possible to extend
records in-place, as long as they're at the end of the file, so
the premature record terminator might be "erased" if later I/O,
after the fflush(), were to complete the "line" and add an
explicit \n.  It would require some fairly ugly state variables
in the emulation's "file descriptor," of questionable payoff.

(DEC's VMS C RTL uses by default a previously-unimportant VMS
file type called "stream LF", rather than the standard
record-oriented carriage-control text files, to circumvent these
kinds of difficulties.  Unfortunately, other VMS utilities
historically had only sporadic understanding of stream-LF files,
to the point that the first versions of DEC's VMS C compiler
failed Ritchie's generality/usefulness test: C program text
output from a C program was not acceptable as input to the C
compiler.  C's growing popularity has forced DEC to expand the
handling of stream-LF files elsewhere in VMS, including, you'll
be relieved to know, the input section of the C compiler.)