4

I'm doing some basic file reading using open, read, and close (Files are opened with access mode O_RDONLY).

When it comes time to close the file, I can't think of a good way to handle a possible file close error to make sure that the file is closed properly.

Any suggestions?

zztops
  • 694
  • 1
  • 5
  • 11

2 Answers2

6

From my experience close will succeed even when it fails. There are several reasons for this.

I suspect that one of the big reasons close started to fail on some operating systems was AFS. AFS was a distributed file system from the '80s with interesting semantics - all your writes were done to a local cache and your data was written to the server when you close the file. AFS also was cryptographically authenticated with tokens that expired after a time. So you could end up in an interesting situation where all the writes you did to a file were done while your tokens were valid, but close which actually talked to the file server could be done with expired tokens meaning that all the data you wrote to the local cache was lost. This is why close needed to communicate to the user that something went wrong. Most file editors handle this correctly (emacs refuses to mark the buffer as not dirty, for example), but I've rarely seen other applications that can handle this.

That being said, close can't really fail anyway. close is implicit during exit, exec (witch close-on-exec file descriptors) and crashes that dump core. Those are situations where you can't fail. You can't have exit or a crash fail just because closing the file descriptor failed. What would you do when exit fails? Crash? What if crashing fails? Where do we run after that? Also, since almost no one checks for errors in close if failing was common you'd end up with file descriptor leaks and information leaks (what if we fail to close some file descriptor before spawning an unprivileged process?). All this is too dangerous for an operating system to allow so all operating systems I've looked at (*BSD, Linux, Solaris) close the file descriptor even if the underlying filesystem close operation has failed.

In practice this means that you just call close and ignore any errors it returns. If you have a graceful way of handling it failing like editors do you can send a message to the user and let the user resolve the problem and reopen the file, write down the data and try to close again. Don't do anything automatically in a loop or otherwise. Errors in close are beyond your control in an application.

Art
  • 19,807
  • 1
  • 34
  • 60
-2

I guess the best thing to do is to retry a couple of times, with some short delay between attempts, then log the problem and move on.

The manual page for close() mentions EINTR as being a possible error, which is why re-trying can help.

If your program is about to exit anyway, I wouldn't worry too much about this type of error checking, since any resources you've allocated are going to be de-allocated by the operating system anyway (on most/typical desktop/server platforms, that is).

unwind
  • 391,730
  • 64
  • 469
  • 606
  • Thanks for the quick reply. Wanted to make sure I wasn't missing anything/ – zztops May 17 '13 at 12:23
  • 1
    At least on Linux it seems to be a bad idea to call `close()` mutiple times: https://lkml.org/lkml/2002/7/17/165 – alk May 17 '13 at 12:25
  • 2
    This is a terrible idea. Even the operating systems where `close` returns errors (which by itself is a terrible idea) the file descriptor is closed on error. Calling `close` again will either not do anything or close an unrelated file descriptor that some other thread opened. – Art May 17 '13 at 12:35
  • well, looks like I'll just roll the dice and not error check then – zztops May 17 '13 at 12:39
  • @zztops: This surely is the badest solution. Check the result and log it if it indicates an error! – alk May 17 '13 at 12:41