wryun / es-shell

es: a shell with higher-order functions
http://wryun.github.io/es-shell/
Other
313 stars 26 forks source link

Does not close opened descriptors during unwind #8

Closed mwgamera closed 9 years ago

mwgamera commented 11 years ago

When exception is thrown from inside of any command with redirected I/O ($&openfile), the opened file is left open with no possibility to close it.

ls -l /dev/fd/
catch @ {} {
  let (fd = <=%newfd)
  %open $fd /dev/zero { $&throw anything }
}
ls -l /dev/fd/

As a simple workaround, one could catch all the exceptions and manually pass them ‘outside’ the $&openfile for example this way:

let (openfile_real = $fn-%openfile)
fn-%openfile = @ mode fd file code {
  let (exception = ) {
    let (
      result = <={
        $openfile_real $mode $fd $file {
          catch @ { exception = $* } { $code }
        }
      }
    ) {
      ~ $exception || throw $exception
      result $result
    }
  }
}
wryun commented 11 years ago

Never looked at %openfile and friends, so I don't know much about this (well, strictly speaking I'm very much an es beginner generally). Your workaround seems good, but is it the sort of thing that should go in initial.es? i.e. is there a cleaner solution? Is there some reason to not have this kind of workaround in the basic setup, but instead force people to do it manually if necessary (flexibility?)? I know, strictly speaking it's always 'necessary', but...

Suggestions?

mwgamera commented 11 years ago

Much cleaner solution would be to fix the underlying $&openfile primitive. I opened the issue because I won't do this myself in any foreseeable future. The workaround above should work just fine when put into initial.es, but it's still just a workaround.

wryun commented 11 years ago

This just bit me the yesterday... now I regret not getting round to putting your workaround in my esrc at least. Didn't realise a simple SIGINT would cause this.

mwgamera commented 9 years ago

Awesome, thanks!