1. 6

  2. 11

    I think the second update gets there, but close() is probably the wrong function to be checking. if you care about durability, you take care of that explicitly by calling sync. this mirrors accepted practice in C, where I generally kind of roll my eyes at while (close(fd) != 0) style bananas.

    1. 1

      Meh. There’s generally nothing worthwhile you can do if close fails, so checking for errors there is pretty pointless.

      1. 3

        Most programmers have trouble doing more than log an error when it occurs, so it seems appropriate to at least do that. Maybe you’ll get lucky and be able to explain why data on an NFS mount went missing.

        Personally, I can’t remember the last time I wrote a program that wrote a file I cared a lot about. Often, I write to stdout and let my shell handle file writes. YOLO, or something, right?

        1. 2

          Close doesn’t flush your file system buffers, which means it will likely succeed even if NFS fails, your disk dies, or anything else goes wrong on the physical layer.

          As tedu said, if you care, you want to sync, and check the result there.

          1. 1

            The man page on Linux has this to say:

            Not checking the return value of close() is a common but nevertheless serious programming error. It is quite possible that errors on a previous write(2) operation are first reported at the final close(). Not checking the return value when closing the file may lead to silent loss of data. This can especially be observed with NFS and with disk quota.

            1. 4

              It can also return an error and not lose data, which I think is the case with EINTR. But the file is still closed. So now you have a busted fd, that you can’t close again (EBADF, or worse, if your program is threaded, now you close the wrong file!), but no way of knowing if data was saved or lost. If you care about lost writes, the sane thing is to use fsync, which offers you some better choices in how to handle the error.

      2. 1

        Are there any languages that have a workable solution to this general problem (you must manually call flush is barely workable)?