Still unsafe #7

Closed
trystan opened this Issue Apr 19, 2011 · 1 comment

Projects

None yet

1 participant

@trystan
Owner
trystan commented Apr 19, 2011

(from Felipe Almeida Lessa felipe.lessa@gmail.com of the Haskell mailing list)

Hello!

It's nice to see that now you're using /dev/null whenever possible :).

Now, I think this code is exception-unsafe:

....

It may leave some handles pointing to /dev/null and/or the tmpHandle
opened should an exception be raised inside the handler [*]. This may
also happen if one of the hDuplicateTo fails. I think it should be
safer to write:

-- | Run an IO action while preventing all output to the given handles.
hSilence :: [Handle] -> IO a -> IO a
hSilence handles action = bracket (openFile "/dev/null" AppendMode)
                             hClose
                             prepareAndRun
 where
  prepareAndRun tmpHandle = go handles
    where
      go []     = action
      go (h:hs) = bracket (do old <- hDuplicate h
                              hDuplicateTo tmpHandle h
                              return old)
                          (\old -> hDuplicateTo old h)
                          (\_   -> go hs)

This creates one bracket per handle, plus one bracket for the
/dev/null.

Cheers,

[*] Note that I'm not sure if an exception can be raised inside
an exception handler. I tried to read the docs but couldn't find
anything. Therefore, I think it's safer to assume that it is
possible.

@trystan trystan was assigned Apr 19, 2011
@trystan
Owner
trystan commented Apr 19, 2011

Fixed in v1.1.2

@trystan trystan closed this Apr 19, 2011
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment