Nonflushing fclose() is a PROBLEM

Chris Wagner jwag at moose.asd.sgi.com
Tue Jun 18 12:57:21 AEST 1991


In article <8810253 at um.cc.umich.edu>, Tim_Buxton at UM.CC.UMICH.EDU writes:
|> Netlanders:
|>  
|> We are having serious intermittent problems as we *try* to communicate
|> between processes  using fscanf() and fprintf().  We had used
|> pipes previously, with success.  When we added signal handling
|> to the processes however, the pipes "broke", and according to the
|> documentation, this is Just the Way It Is; pipes become nonblocking
|> when signals are used.  Writing to/reading from a scratch file
|> seemed a logical alternative.
|>  
|> Our problem seems to happen because the system INSISTS on
|> writebehind buffering with fprintf(), and the fscanf() just
|> plows ahead and tries to read junk when the fprintf() output
|> is delayed by other traffic on the system.  The only way
|> we have found to fix the problem is to put a sleep() command
|> in to (maybe) insure the system has time to flush its buffer.
|> This is clearly unreliable, however.  Has anyone found a
|> workaroud to this problem?
|>  
|> The code works (roughly) as follows:
|>  
|>  PROCESS 1
|>  
|>        .
|>        .
|>        .
|>   fp=fopen("file"...
|>   fprintf(fp,"%s\n", stuff....
|>   fclose(fp); /* this does not flush the buffer before proceeding*/
|>   <send signal to process 2 that file is complete>
|>  
|>  
|>  PROCESS 2
|>  
|>        .
|>        .
|>        .
|>   <wakes up on signal from PROCESS 1>
|>   sleep(2);  /* this works but is wasteful and undependable */
|>   fp=fopen("file"...
|>   fscanf(fp,"%s", maybegarbage ); /* here the problem
|>                                   happens when garbage
|>                                   is read in sometimes */
|>  
|> /* end of pseudocode */
|>  
|>  
|> The Hotline has said yes, this is a problem, but that the low-level
|> open(fileid, O_SYNC|WRITEONLY); would *actually* flush the buffer
|> *before* sending the signal in PROCESS 1.  This will involve rewriting
|> substantial code, and I would appreciate hearing about easier workarounds
|> that others have found.  Whatever we find to be easiest, I will
|> summarize to the net once we prove it works.  Thanks.
|>  
|>                          Tim Buxton
|>                          OptiMetrics, Inc.
|>                          Tim_Buxton at um.cc.umich.edu
|>  
|>  

-- 
I am a bit confused - a call to read a pipe can be interrupted
by a signal, but the read will return EINTR - you could just loop
and read again. The problem comes in using fscanf - the stdio
library isn;t so could about getting interrupts.
You could switch to doing your own read/write(2) system calls, then
calling sscanf and sprintf to do the formatting.

As for fflush/fclose - it definetly flushes out all write-behind data
from the user process into the system, where any read will find it.
Doing O_SYNC is defintely NOT the right answer! this synchrously
writes stuff to disk - there is no reason for this.

If you aren;t worried about getting signals during the read
(which you appearently are not since you are willing to
switch to a temp file), then you could also simply go back
to pipes and fprintf/scanf and simply put is sighold(3) around those
to temporarily block signals.

----
Chris Wagner (jwag at sgi.com)



More information about the Comp.sys.sgi mailing list