Yesterday I made the claim that close() can’t fail in a meaningful way.  Meaning that if it’s invoked on an object in a state that does not support close(), it’s a programming/coding error.

I believe that this is correct but we’ll see that there are challenges as a result of it.

Let’s explore briefly what might happen if it could fail for environmental factors.  Are you going to write this code:

int main(int argc, const char *argv[]) {
   for (int i=1; i<argc; i++) {
      FILE *fp = fopen(argv[i], “w”);
      if (fp == NULL) {
         perror(“Unable to open file”);
         exit(EXIT_FAILURE);
      }
      // This is how it should be written but nobody does...  perror is somewhat lacking

      if (fprintf(fp, “Hello there %s\n”, argv[i]) < 0) {
         perror(“Unable to write to file”);
         fclose(fp); // should this match how fclose() is called below??  probably.
         exit(EXIT_FAILURE);
      }
      // controversial bit:
      while (fclose(fp) == EOF) {
         if (errno != ENOMEM) {
            perror(“Unable to close file”);
            exit(EXIT_FAILURE);
         }
      }
   }

   return EXIT_SUCCESS;
}

Maybe you should but I doubt it.  Maybe we should also loop on EDEADLOCK also?  ENOSPC?  All errors?  Probably not EBADF.  This error code probably means that the file handle/id in the FILE is corrupt.  Who’s going to document what?

My point here is only to try to put the nail in the coffin for resource management termination/close functions having public APIs that include failure modes other than invalid parameter.

[edited 5/3/05 2:11pm PST to fix missing return from main]
[edited 5/4/2001 4:00pm PST to fix missing close when fprintf() fails]