How to tell a file is been close.

Discussion in 'C Programming' started by empriser, May 17, 2007.

  1. empriser

    empriser Guest

    FILE *fp;

    fp = fopen( ... )
    fclose( fp ).


    How do I know if fp has been fclose.
    I know can set fp to NULL after fclose it, then check fp's value to
    solve the problem.
    But, if there have other methods?
     
    empriser, May 17, 2007
    #1
    1. Advertising

  2. empriser said:

    > FILE *fp;
    >
    > fp = fopen( ... )
    > fclose( fp ).


    fclose can fail. Check the return result. (Here, I'm speaking as much to
    myself as to you!)


    > How do I know if fp has been fclose.
    > I know can set fp to NULL after fclose it, then check fp's value to
    > solve the problem.


    Right. When you call fclose, the value of fp becomes indeterminate,
    which means that you are no longer allowed to use that value for any
    purpose. So the best thing you can do is give fp a new value that you
    /can/ use, and NULL is the obvious candidate.


    > But, if there have other methods?


    No.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at the above domain, - www.
     
    Richard Heathfield, May 17, 2007
    #2
    1. Advertising

  3. empriser

    Chris Dollin Guest

    empriser wrote:

    > FILE *fp;
    >
    > fp = fopen( ... )
    > fclose( fp ).
    >
    >
    > How do I know if fp has been fclose.


    You have to remember that you've closed it. (Or, preferably,
    arrange that you don't have to care.)

    > I know can set fp to NULL after fclose it, then check fp's value to
    > solve the problem.


    That doesn't help if there are other copies of `fp`s value.

    A useful trick is to arrange that your file-handling code looks like:

    { FILE* fp = fopenSuitably()
    ; doThingsWithFile( fp )
    ; fclose( fp )
    ; }

    (Don't mind my layout, I'm being experimental today.)

    (Insert check on `fclose` working to taste.)

    Now, this piece of code is so short it's easy to check that
    you never use `fp` after its been closed. (Assuming that
    `doThingsWithFile` doesn't wilfully copy `fp` elsewhere.)

    And sometimes you can arrange that `doThingsWithFile` is a
    function pointer. (If it needs extra state, pass that in too.)

    If most of your file-handling can be done that way, you only need
    to be deeply suspicious of other uses of files.

    Another trick is to have a struct

    struct fileAndBoolean
    { YourBooleanType closed
    ; FILE* fp
    ; }

    Write file-accessing methods on `struct fileAndBoolean*`. Have them
    check whether `closed` is true. Set `closed` on `close()`.

    Whether these tricks are of value to you depends on your context.

    --
    "It's just the beginning we've seen" - Colosseum, /Tomorrow's Blues/

    Hewlett-Packard Limited registered office: Cain Road, Bracknell,
    registered no: 690597 England Berks RG12 1HN
     
    Chris Dollin, May 17, 2007
    #3
  4. empriser

    Tor Rustad Guest

    empriser wrote:
    > FILE *fp;
    >
    > fp = fopen( ... )
    > fclose( fp ).
    >
    >
    > How do I know if fp has been fclose.


    fclose() returns 0 on success.

    > I know can set fp to NULL after fclose it, then check fp's value to
    > solve the problem.


    what is the problem?



    --
    Tor
     
    Tor Rustad, May 17, 2007
    #4
  5. On May 17, 12:11 pm, Richard Heathfield <> wrote:

    > fclose can fail. Check the return result. (Here, I'm speaking as much to
    > myself as to you!)


    The question is: If it fails, what are you supposed to do? fclose can
    obviously fail if I make some programming error, like fclose (fp);
    fclose (fp); where the second call is quite likely to fail. But apart
    from that, what can you do?
     
    christian.bau, May 17, 2007
    #5
  6. empriser

    quarkLore Guest

    On May 18, 1:14 am, "christian.bau" <>
    wrote:
    > On May 17, 12:11 pm, Richard Heathfield <> wrote:
    >
    > > fclose can fail. Check the return result. (Here, I'm speaking as much to
    > > myself as to you!)

    >
    > The question is: If it fails, what are you supposed to do? fclose can
    > obviously fail if I make some programming error, like fclose (fp);
    > fclose (fp); where the second call is quite likely to fail. But apart
    > from that, what can you do?


    Error propagation and catching is a problem in C and in general
    structured programming languages.
    Coming back to the topic. You can check the errno. Check this:
    http://man.he.net/?topic=fclose&section=all

    Check this to know how to use errno: http://www.mkssoftware.com/docs/man5/errno.5.asp
    http://www.unix.geek.org.uk/~arny/info/library_2.html
     
    quarkLore, May 17, 2007
    #6
  7. In article <>,
    christian.bau <> wrote:

    >> fclose can fail. Check the return result. (Here, I'm speaking as much to
    >> myself as to you!)


    >The question is: If it fails, what are you supposed to do? fclose can
    >obviously fail if I make some programming error, like fclose (fp);
    >fclose (fp); where the second call is quite likely to fail. But apart
    >from that, what can you do?


    You can warn the user, so he doesn't delete the old version of his
    data.

    -- Richard
    --
    "Consideration shall be given to the need for as many as 32 characters
    in some alphabets" - X3.4, 1963.
     
    Richard Tobin, May 17, 2007
    #7
  8. Tor Rustad <torust_at_online.no> wrote:
    > empriser wrote:
    > > FILE *fp;
    > >
    > > fp = fopen( ... )
    > > fclose( fp ).
    > >
    > >
    > > How do I know if fp has been fclose.

    >
    > fclose() returns 0 on success.


    Even on failure fp is still effectively closed for all intents and purposes.
    fp becomes (or remains) invalid either way.
     
    William Ahern, May 17, 2007
    #8
  9. christian.bau said:

    > On May 17, 12:11 pm, Richard Heathfield <> wrote:
    >
    >> fclose can fail. Check the return result. (Here, I'm speaking as much
    >> to myself as to you!)

    >
    > The question is: If it fails, what are you supposed to do? fclose can
    > obviously fail if I make some programming error, like fclose (fp);
    > fclose (fp); where the second call is quite likely to fail. But apart
    > from that, what can you do?


    As Richard T points out, you can warn the user. Also, you may still have
    the data in memory, in which case you can prompt for a different
    filename, suggesting to the user that he might like to specify a
    different device.

    "Warn the user" is the very least you can do for /any/ failure (except
    one). Often you can do more, but even if you can't, at least you can
    clue the user in to what is going wrong.

    The one exception, of course, is where the failure is that your program
    can't write to the output device that your user is monitoring (be it
    stderr or some customised dialog routine or whatever). Some days, it
    just isn't worth getting out of bed.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at the above domain, - www.
     
    Richard Heathfield, May 17, 2007
    #9
  10. In article <>,
    Richard Heathfield <> wrote:

    >"Warn the user" is the very least you can do for /any/ failure (except
    >one). Often you can do more, but even if you can't, at least you can
    >clue the user in to what is going wrong.
    >
    >The one exception, of course, is where the failure is that your program
    >can't write to the output device that your user is monitoring (be it
    >stderr or some customised dialog routine or whatever). Some days, it
    >just isn't worth getting out of bed.


    You could sit in a loop, so that the user has to kill the program.
    That should make them think twice about checking the data is intact.

    -- Richard
    --
    "Consideration shall be given to the need for as many as 32 characters
    in some alphabets" - X3.4, 1963.
     
    Richard Tobin, May 17, 2007
    #10
  11. empriser

    Tor Rustad Guest

    William Ahern wrote:
    > Tor Rustad <torust_at_online.no> wrote:
    >> empriser wrote:
    >>> FILE *fp;
    >>>
    >>> fp = fopen( ... )
    >>> fclose( fp ).
    >>>
    >>>
    >>> How do I know if fp has been fclose.

    >> fclose() returns 0 on success.

    >
    > Even on failure fp is still effectively closed for all intents and purposes.
    > fp becomes (or remains) invalid either way.


    fclose(NULL);

    close nothing.

    --
    Tor <torust [at] online [dot] no>
     
    Tor Rustad, May 17, 2007
    #11
  12. On 17 May 2007 13:14:43 -0700, in comp.lang.c , "christian.bau"
    <> wrote:

    >On May 17, 12:11 pm, Richard Heathfield <> wrote:
    >
    >> fclose can fail. Check the return result. (Here, I'm speaking as much to
    >> myself as to you!)

    >
    >The question is: If it fails, what are you supposed to do? fclose can
    >obviously fail if I make some programming error, like fclose (fp);
    >fclose (fp); where the second call is quite likely to fail. But apart
    >from that, what can you do?


    Depends why it failed. Could be tht the OS can't flush the buffers to
    disk because there's no space at present, or it could be the
    filehandle got corrupted, etc etc. Solutions would differ, and you'd
    need to check other information to determine how to respond.
    --
    Mark McIntyre

    "Debugging is twice as hard as writing the code in the first place.
    Therefore, if you write the code as cleverly as possible, you are,
    by definition, not smart enough to debug it."
    --Brian Kernighan
     
    Mark McIntyre, May 17, 2007
    #12
  13. empriser

    Tor Rustad Guest

    christian.bau wrote:
    > On May 17, 12:11 pm, Richard Heathfield <> wrote:
    >
    >> fclose can fail. Check the return result. (Here, I'm speaking as much to
    >> myself as to you!)

    >
    > The question is: If it fails, what are you supposed to do? fclose can
    > obviously fail if I make some programming error, like fclose (fp);
    > fclose (fp); where the second call is quite likely to fail. But apart
    > from that, what can you do?


    What type of program and system do you have in mind?

    If we ignore trivial case of an invalid stream pointer on input,
    typically a write to file failure has caused your fclose() error.

    A very simplistic recovery, would be to retry the operation on the file,
    but that is a gamble, possibly the file is already in a corrupted state
    and further write to it, would only do more harm. On Linux EFBIG, it is
    rather pointless to retry..

    So, it depend on the error value set in errno, e.g. Linux EFAULT is bad,
    your program is possibly in an undefined state, and the best thing to do
    is usually exit ASAP.

    Making programs fault tolerant is a complex topic, if I really don't
    need that, I follow the "worse is better" design

    http://www.jwz.org/doc/worse-is-better.html

    and just log error to the system log and exit.


    --
    Tor <torust [at] online [dot] no>
     
    Tor Rustad, May 17, 2007
    #13
  14. empriser

    Al Balmer Guest

    On 17 May 2007 13:14:43 -0700, "christian.bau"
    <> wrote:

    >On May 17, 12:11 pm, Richard Heathfield <> wrote:
    >
    >> fclose can fail. Check the return result. (Here, I'm speaking as much to
    >> myself as to you!)

    >
    >The question is: If it fails, what are you supposed to do? fclose can
    >obviously fail if I make some programming error, like fclose (fp);
    >fclose (fp); where the second call is quite likely to fail. But apart
    >from that, what can you do?


    Notify the user, probably. Other than that, possible action depends on
    why the call failed, and both the reasons and the error codes are
    implementation dependent.

    --
    Al Balmer
    Sun City, AZ
     
    Al Balmer, May 18, 2007
    #14
  15. quarkLore <> writes:
    > On May 18, 1:14 am, "christian.bau" <>
    > wrote:
    >> On May 17, 12:11 pm, Richard Heathfield <> wrote:
    >>
    >> > fclose can fail. Check the return result. (Here, I'm speaking as much to
    >> > myself as to you!)

    >>
    >> The question is: If it fails, what are you supposed to do? fclose can
    >> obviously fail if I make some programming error, like fclose (fp);
    >> fclose (fp); where the second call is quite likely to fail. But apart
    >> from that, what can you do?

    >
    > Error propagation and catching is a problem in C and in general
    > structured programming languages.
    > Coming back to the topic. You can check the errno.


    Yes, but the C standard doesn't say that fclose() sets errno on
    failure (though many implementations do so).

    Set errno to 0 before the call, and check its value after the call
    *only* if fclose() reported an error by returning EOF. (fclose()
    returns 0 on success, EOF on error.)

    > Check this:
    > http://man.he.net/?topic=fclose&section=all
    >
    > Check this to know how to use errno:
    > http://www.mkssoftware.com/docs/man5/errno.5.asp
    > http://www.unix.geek.org.uk/~arny/info/library_2.html


    Based on a quick glance, that looks like good information, but some of
    it is system-specific, and it doesn't mention the need to set errno to
    0 before a call.

    Consider a system where a given function *doesn't* set errno. Before
    the call, it could have any arbitrary value from some previous error.
    If the call fails without setting errno, you could end up using bogus
    information.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, May 18, 2007
    #15
  16. Tor Rustad <torust_at_online.no> writes:
    > William Ahern wrote:
    >> Tor Rustad <torust_at_online.no> wrote:
    >>> empriser wrote:
    >>>> FILE *fp;
    >>>>
    >>>> fp = fopen( ... )
    >>>> fclose( fp ).
    >>>>
    >>>>
    >>>> How do I know if fp has been fclose.
    >>> fclose() returns 0 on success.

    >> Even on failure fp is still effectively closed for all intents and
    >> purposes.
    >> fp becomes (or remains) invalid either way.

    >
    > fclose(NULL);
    >
    > close nothing.


    I'm not sure what your point is, but fclose(NULL) invokes undefined
    behavior. fclose "causes the stream pointed to by stream to be
    flushed and the associated file to be closed"; if there is no such
    stream, the behavior is undefined by omission.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, May 18, 2007
    #16
  17. empriser

    B. Augestad Guest

    Keith Thompson wrote:
    > Tor Rustad <torust_at_online.no> writes:
    >> William Ahern wrote:
    >>> Tor Rustad <torust_at_online.no> wrote:
    >>>> empriser wrote:
    >>>>> FILE *fp;
    >>>>>
    >>>>> fp = fopen( ... )
    >>>>> fclose( fp ).
    >>>>>
    >>>>>
    >>>>> How do I know if fp has been fclose.
    >>>> fclose() returns 0 on success.
    >>> Even on failure fp is still effectively closed for all intents and
    >>> purposes.
    >>> fp becomes (or remains) invalid either way.

    >> fclose(NULL);
    >>
    >> close nothing.

    >
    > I'm not sure what your point is, but fclose(NULL) invokes undefined
    > behavior. fclose "causes the stream pointed to by stream to be
    > flushed and the associated file to be closed"; if there is no such
    > stream, the behavior is undefined by omission.
    >


    I was puzzled by Tors post too. Some investigation reveals that the man
    page for fclose() on Cygwin confirms this. Here's what it says:

    `fclose' returns `0' if successful (including when FP is `NULL'
    or not an open file); otherwise, it returns `EOF'.

    So on such systems fclose(NULL) seems to be fine. Even
    FILE *fp = fopen("whatever", "r");
    fclose(fp);
    fclose(fp);
    fclose(fp);
    should work on that implementation. A Very Bad Choice, IMO. Why not
    stick to the standard?


    Bjørn



    --
    Looking for an embeddable web server?
    http://www.metasystems.no/products/highlander/index.html
     
    B. Augestad, May 18, 2007
    #17
  18. "B. Augestad" <> writes:
    [...]
    > I was puzzled by Tors post too. Some investigation reveals that the
    > man page for fclose() on Cygwin confirms this. Here's what it says:
    >
    > `fclose' returns `0' if successful (including when FP is `NULL'
    > or not an open file); otherwise, it returns `EOF'.
    >
    > So on such systems fclose(NULL) seems to be fine. Even
    > FILE *fp = fopen("whatever", "r");
    > fclose(fp);
    > fclose(fp);
    > fclose(fp);
    > should work on that implementation. A Very Bad Choice, IMO. Why not
    > stick to the standard?


    I agree that it's a bad choice, but it does stick to the standard.
    Returning 0 is perfectly consistent with undefined behavior.

    Incidentally, it's not clear to me from the standard whether

    FILE *fp = fopen("whatever", "r"); /* assume success */
    fclose(fp);
    fclose(fp);

    invokes undefined behavior or not. C99 7.19.5.1 says that "the stream
    is disassociated from the file", but it doesn't say that the stream no
    longer exists after that.

    I think one could argue that the second fclose() must succeed, or that
    it must fail, or that it invokes undefined behavior. (Or maybe it's
    just too early in the morning.)

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, May 18, 2007
    #18
  19. In article <>,
    Keith Thompson <> wrote:

    >Incidentally, it's not clear to me from the standard whether
    >
    > FILE *fp = fopen("whatever", "r"); /* assume success */
    > fclose(fp);
    > fclose(fp);
    >
    >invokes undefined behavior or not.


    I'm not going to work through the standard right now, but this has to
    be undefined behaviour. Otherwise FILE objects couldn't be re-used,
    which they are in many implementations (and were even before C89).

    Consider:

    FILE *fp1 = fopen("whatever1", "r"); /* assume success */
    fclose(fp1);
    FILE *fp2 = fopen("whatever2", "r"); /* assume success */

    In many implementations fp1 and fp2 are equal (yes, in theory it's
    probably undefined behaviour to compare them). Calling fclose(fp1)
    again at the end will close the second file.

    -- Richard
    --
    "Consideration shall be given to the need for as many as 32 characters
    in some alphabets" - X3.4, 1963.
     
    Richard Tobin, May 18, 2007
    #19
  20. empriser

    Tor Rustad Guest

    Keith Thompson wrote:

    > I'm not sure what your point is, but fclose(NULL) invokes undefined
    > behavior.



    Agreed, fclose(NULL) is UB.

    --
    Tor <torust [at] online [dot] no>
     
    Tor Rustad, May 18, 2007
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Terry Olsen
    Replies:
    3
    Views:
    667
    Eliyahu Goldin
    Jul 12, 2005
  2. Paul Dale
    Replies:
    1
    Views:
    303
    Rocco Moretti
    Sep 22, 2005
  3. Simon Elliott
    Replies:
    10
    Views:
    1,902
    msalters
    Sep 8, 2005
  4. Kevin Audleman
    Replies:
    2
    Views:
    838
    Kevin Audleman
    Apr 3, 2007
  5. Iñaki Baz Castillo
    Replies:
    7
    Views:
    917
    Iñaki Baz Castillo
    Jan 12, 2010
Loading...

Share This Page