fopen() and memory shortage

Tapani Tarvainen tarvaine at tukki.jyu.fi
Tue Feb 6 22:53:59 AEST 1990


Two days ago I had this little trouble with a program which, to make
it brief, reads a file into memory, does something to it and writes it
back, saving the original as a backup with another name (= an editor).
Normally it works just fine, but in this instance it complained "can't
open file for writing"; I then exited without saving and found that it
had destroyed the original file but failed to back it up.

The relevant code looks something like this:

	if (fexist(fname))
		/* backup */
	if (!(fp = fopen(fname,"w))
		/* error message */

I soon found out that fexist() returned 0 even though the file definitely
existed.  Here's what fexist() looked like (slightly trimmed):

int fexist(fname)
char *fname;
{
        FILE *fp;        
        if ((fp = fopen(fname, "r")) == NULL)
                return(0);
        fclose(fp);
        return(1);
}

I had to sleep over it before I figured out what's wrong:
fopen() needs memory for buffering, and there wasn't enough left.
I replaced fopen() and fclose() with open() and close(),
and presto! it worked.

I can't help wondering why the author had used buffered calls in the
first place, since nothing is read from the disk anyway; is there
some situation where open()/close() wouldn't work (are they less
portable perhaps)?

After fixing fexist() I'm now in a situation where the backup will
be created properly, but saving the file still doesn't succeed.
The fopen() fails, but open() inside it succeeds, effectively
destroying the file.
I can think of a couple of ways to handle this, but I don't
really like any of them:
(1) using unbuffered I/O for the writing (yuck!);
(2) malloc()ing the buffer earlier and writing my own buffered output
    routine (feels like re-inventing the wheel);
(3) malloc()ing enough memory earlier and free()ing it just before
    the fopen() (kind of silly, and where do I figure out how much
    memory fopen() needs -- portability is an issue);
(4) keeping a stream open throughout for all writes.

Suggestions, anyone?

(I am using TurboC 2.0 in MS-DOS, if it matters.)
-- 
Tapani Tarvainen    (tarvaine at jyu.fi, tarvainen at finjyu.bitnet)



More information about the Comp.lang.c mailing list