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