Question

See the following code block, how I can make sure a FILE object is not closed before I call fclose on it? BTW, is it safe to call fclose twice?

    FILE* f = fopen('test.txt')

    //some code here, f may be closed by someone, but they may not set it to NULL
    ...


    /// I want to make sure f is not closed before, how can I do it here?
    if(...)
    {
       fclose(f)
    }
Was it helpful?

Solution

No, you have to keep track of it yourself. This is analagous to the question of telling if a pointer to an allocated block has been freed. There could be no way to do such a test because the pointer is no longer valid. The same applies with FILE *. Once you have closed the file, any attempt to access the underlying object results in undefined behavior.

Updated:

Beware, to quote the Linux man page:

The  behaviour  of fclose() is undefined if the stream parameter is an
illegal pointer, or is a descriptor already passed to a previous invo‐
cation of fclose().

Keep in mind that undefined behavior doesn't mean that it will crash or that it won't "work". It means that no particular behavior is guaranteed and that the operation is unsafe. Accessing a FILE struct after fclose() is a very bad idea.

OTHER TIPS

Whenever you call fclose() anywhere in the program, you should set the FILE* file-pointer to NULL as follows, which you can check later during the cleanup at the end of the file.

fclose(f)
f = NULL;

The cleanup section at the end of the file would look like:

if (f != NULL)
{
    fclose(f);
    f = NULL;
}

Paste fclose source code of android-bionic: (fclose.c file)

int fclose(FILE *fp)
{
    int r;

    if (fp->_flags == 0) {  /* not open! */
        errno = EBADF;
        return (EOF);
    }
    FLOCKFILE(fp);
    WCIO_FREE(fp);
    r = fp->_flags & __SWR ? __sflush(fp) : 0;
    if (fp->_close != NULL && (*fp->_close)(fp->_cookie) < 0)
        r = EOF;
    if (fp->_flags & __SMBF)
        free((char *)fp->_bf._base);
    if (HASUB(fp))
        FREEUB(fp);
    if (HASLB(fp))
        FREELB(fp);
    fp->_r = fp->_w = 0;    /* Mess up if reaccessed. */
    fp->_flags = 0;     /* Release this FILE for reuse. */
    FUNLOCKFILE(fp);
    return (r);
}

It seems safe to call fclose on a closed FILE object.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top