Path: utzoo!utgpu!news-server.csri.toronto.edu!bonnie.concordia.ca!uunet!elroy.jpl.nasa.gov!decwrl!sgi!shinobu!fido.asd.sgi.com!moose.asd.sgi.com!jwag From: jwag@moose.asd.sgi.com (Chris Wagner) Newsgroups: comp.sys.sgi Subject: Re: Nonflushing fclose() is a PROBLEM Message-ID: <1991Jun18.025721.609@fido.asd.sgi.com> Date: 18 Jun 91 02:57:21 GMT References: <8810253@um.cc.umich.edu> Sender: news@fido.asd.sgi.com (Usenet News Admin) Organization: Silicon Graphics, Research & Development Lines: 82 In article <8810253@um.cc.umich.edu>, Tim_Buxton@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*/ |> |> |> |> PROCESS 2 |> |> . |> . |> . |> |> 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@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@sgi.com)