[comp.lang.c] when to fflush ?

siva@bally.Bally.COM (Siva Chelliah) (06/13/91)

Hi,
   I have a question.  Does seeking to the end of a file causes a flushing
of the buffer ? In my opinion it should not.
   Look at the following program.  Even though I write only 5 bytes, 
when you do a cat on test.out , you see "hello."  Move the sleep(500)
before fseek , and you won't see it.   It happened on both IBM RT running
AIX 2.1 and RS 6000 running AIX 3.1.  Please comment.

Thanks , 

Siva
------------------------------- 
#include <stdio.h>
main ()
{
	FILE *fp;
	char buf[80];
	strcpy(buf,"hello\n");
	system ("touch test.out");      /* just to create the file */
	fp = fopen ("test.out","r+");
	fseek(fp,0L,0);         /* seek to start of file - you do not need this */
	fwrite(buf,strlen(buf),1,fp);
	fseek(fp,0L,2);                 /* seek to end of file */
	sleep(500);
   fclose (fp);
}

	
	
  
-- 
/=*=*=*=*=*=*=*=*=*=*=*=*=*=*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\
| Siva@bally.bally.com     | He who asks is a fool for five minuites,|
| Bally Systems,           | but he who does not ask remains a fool  |
| Reno,  NV 89502          | forever      -Old Chinese saying        |

wargaski@casbah.acns.nwu.edu (Robert E. Wargaski Jr.) (06/14/91)

One should fflush() early and fflush() often.

Rob

-- 

Rob Wargaski
r-wargaski@nwu.edu			Colby is good.
ACNS DSS, Northwestern University

karish@mindcraft.com (Chuck Karish) (06/14/91)

In article <504@bally.Bally.COM> siva@bally.Bally.COM (Siva Chelliah) writes:
>   I have a question.  Does seeking to the end of a file causes a flushing
>of the buffer ? In my opinion it should not.
>   Look at the following program.  Even though I write only 5 bytes, 
>when you do a cat on test.out , you see "hello."  Move the sleep(500)
>before fseek , and you won't see it.   It happened on both IBM RT running
>AIX 2.1 and RS 6000 running AIX 3.1.  Please comment.

The system is free to flush the output whenever it finds it
convenient to do so.  If you depend on a particular predictable
flushing strategy, you'll wind up with code that's not at all
portable and which is likely to be broken by future quiet
changes to the system.
-- 

	Chuck Karish		karish@mindcraft.com
	Mindcraft, Inc.		(415) 323-9000

jona@iscp.Bellcore.COM (Jon Alperin) (06/14/91)

And always remember to wash your hands afterwards! :=}

  (sorry....it's early friday morning and I couldn't resist...)
-- 
Jon Alperin
Bell Communications Research

---> Internet: jona@iscp.bellcore.com
---> Voicenet: (908) 699-8674
---> UUNET: uunet!bcr!jona

* All opinions and stupid questions are my own *

steve@taumet.com (Stephen Clamage) (06/14/91)

siva@bally.Bally.COM (Siva Chelliah) writes:


>   I have a question.  Does seeking to the end of a file causes a flushing
>of the buffer ? In my opinion it should not.

It is an implementation issue, but I don't see why you would expect the
buffer NOT to be flushed in general upon a seek.  Consider the alternative:

When you write to a stdio FILE, the data you write must go to the current
file position.  If you then seek and do another write, that data must
go to the new file position.  If you seek and read, the read might
involve all or part of the buffered data.  This leaves the implementation
with two main choices:

1.  Always flush just before seeking.  This is always correct (satisfies
    all ANSI C requirements) and takes no extra bookkeeping.

2.  Keep track of where each buffered piece of data goes, and when you
    can't stand it any more, write out all the pieces you have saved.
    When you finally do a flush, you have to be careful to seek to each
    saved position and write the piece of buffer in the order in which the
    buffered write calls occurred from user code.  Each read must also be
    inspected to see whether it corresponds to any of the pieces of data
    saved up.  A read could involve several of the pieces, and these pieces
    might have overwritten one another.  When satisfying the read request,
    all this must be taken into account.  In other words, you must duplicate
    the functionality of the file system in your buffering scheme.

Which would YOU rather implement and verify for correctness?
-- 

Steve Clamage, TauMetric Corp, steve@taumet.com

dls@achilleus.austin.ibm.com (David Skeen) (06/15/91)

The description of fseek() in the X/Open Portability Guide (issue 3)
says that "If the stream is writable and buffered data had not been
written to the underlying file, fseek() will cause the unwritten data
to be written to the file and mark the st_ctime and st_mtime fields of
the file for update."  I did a quick scan of POSIX 1003.1-1990, but
didn't find such an explicit statement.
--
Dave Skeen                     IBM Internal: dls@achilleus.austin.ibm.com
D61/803  Zip 2603              IBM VNET:     SKEEN at AUSTIN
Austin, TX 78758               Internet:     dls@dce.austin.ibm.com

mouse@thunder.mcrcim.mcgill.edu (der Mouse) (06/16/91)

In article <504@bally.Bally.COM>, siva@bally.Bally.COM (Siva Chelliah) writes:

> Does seeking to the end of a file causes a flushing of the buffer ?

Possibly; this depends on the implementation and possibly many other
things you have no control over, like temporary system memory
shortages.

> Look at the following program.  Even though I write only 5 bytes,

6, actually, counting the newline.

> when you do a cat on test.out , you see "hello."

Why is this surprising?  Isn't that what you wrote?  (Actually, it's
not; you wrote a newline as the sixth character instead of a period.
I'll take that to be ignorable.)

> 	FILE *fp;
> 	char buf[80];
> 	strcpy(buf,"hello\n");
> 	system ("touch test.out");      /* just to create the file */

This isn't needed; the fopen creates it if it's not there already.
(Assuming a non-buggy system, and assuming the open succeeds - which I
notice you don't check for.)

> 	fp = fopen ("test.out","r+");
> 	fseek(fp,0L,0);         /* seek to start of file - you do not need this */
> 	fwrite(buf,strlen(buf),1,fp);
> 	fseek(fp,0L,2);                 /* seek to end of file */
> 	sleep(500);

So, on the implementations where you observe this behavior, fseek()
chooses to flush the stdio buffer.  There is nothing wrong with this;
the implementation may flush the buffer at any time it pleases.  (The
only requirement is that it must flush at certain times, such as when
you call fflush; there are no times at which it must not flush.)

					der Mouse

			old: mcgill-vision!mouse
			new: mouse@larry.mcrcim.mcgill.edu

scs@adam.mit.edu (Steve Summit) (06/18/91)

In article <766@taumet.com> steve@taumet.com (Stephen Clamage) writes:
>When you write to a stdio FILE, the data you write must go to the current
>file position.  If you then seek and do another write, that data must
>go to the new file position.  If you seek and read, the read might
>involve all or part of the buffered data.  This leaves the implementation
>with two main choices:
>
>1.  Always flush just before seeking.  This is always correct (satisfies
>    all ANSI C requirements) and takes no extra bookkeeping.
>
>2.  Keep track of where each buffered piece of data goes, and when you
>    can't stand it any more, write out all the pieces you have saved...

Actually, there's a case Steve left out.  If an fseek is "small,"
its target may correspond to a location already mapped into the
existing stdio buffer.  It is (or ought to be) a simple operation
to note this case and readjust the stdio data structures without
flushing the buffer or lseek(2)'ing the underlying (integer) file
descriptor.

This strategy is complicated, however, by the fact that:

     1.	An "r+" or "w+" stream may change from reading to writing
	around an fseek (fseek on such a stream therefore has to
	flush the buffer completely to allow a sane
	implementation, since it can't tell if the next I/O
	operation will reverse direction), and

     2.	fseek is supposed to erase any memory of ungetc'ed
	characters.

Number 2 kills the optimization (unless you use a separate buffer
for all pushback), which always seemed to me to be a bit of a
shame.

                                            Steve Summit
                                            scs@adam.mit.edu

scairns@zamboni..citib (Scott Cairns) (06/26/91)

In article <1991Jun13.174242.17669@casbah.acns.nwu.edu> wargaski@acns.nwu.edu writes:
>
>One should fflush() early and fflush() often.
>
>Rob
>
>-- 
>
>Rob Wargaski
>r-wargaski@nwu.edu			Colby is good.
>ACNS DSS, Northwestern University

Or as M.C. Hammer sings: "You can't fflush() this!"

Sorry... couldn't resist.