Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Handling an error from close is a bad way to handle the error, because the file is already closed, so you are pretty much stuffed.

You want to call fsync() instead, and grab the error there, which will prevent you from being able to get an error from close() - see "Dealing with error returns from close()" in https://www.man7.org/linux/man-pages/man2/close.2.html

If you get it on close, you have ~no idea which operation failed.

Obviously doing it on the operation allows you to wrap it up in the handling of the operation and allows you to do RAII (or DIRR as it probably should be known).

(The EBADF option is nonsense in a properly developed application, and should cause a panic. The EINTR position is just a mess.)



Error-on-close is basically another form of error-on-destruct, and like you say it doesn't make much sense to raise an error about something that no longer exists. It's not RAII that's wrong here, but the messy semantics of close() and its use as an ad-hoc asynchronous error reporting mechanism.


Of course, other flow control options are available which also prevent this mess - e.g:

  int failed = with_file("foo", |file|{
       write(file, "bar");
  });

  fn with_file(char* foo, lambda: Fn(File)){
    let f = open(foo);
    if !f { return f; }
    let err = lamda(f);
    let cerr = close(f);
    if !err {
       return err;
    }
    return cerr;
  }


Is this Rust or a different language?


Looks like a mix of Rust and C. Like a French person trying to speak English, but still saying half of the words in French.


I was aiming for pseudo-code. You can write it in C, but it's a little less readable due to the lack of first class lamdas.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: