When hGetContents caught an error it was closing the handle and then
throwing the exception, without updating the handle with the new
closed state. This lead to a double-closed, which was the cause of
*** glibc detected *** ./Setup: double free or corruption
when iconv_close was called twice on the decoder.
See http://hackage.haskell.org/trac/hackage/ticket/609
import GHC.IO.Buffer
import qualified GHC.IO.BufferedIO as Buffered
import GHC.IO.Exception
import GHC.IO.Buffer
import qualified GHC.IO.BufferedIO as Buffered
import GHC.IO.Exception
import GHC.IO.Handle.Types
import GHC.IO.Handle.Internals
import qualified GHC.IO.Device as IODevice
import GHC.IO.Handle.Types
import GHC.IO.Handle.Internals
import qualified GHC.IO.Device as IODevice
debugIO ("hGetContents caught: " ++ show e)
-- We might have a \r cached in CRLF mode. So we
-- need to check for that and return it:
debugIO ("hGetContents caught: " ++ show e)
-- We might have a \r cached in CRLF mode. So we
-- need to check for that and return it:
- if isEOFError e
- then if not (isEmptyBuffer buf)
- then return (handle_', "\r")
- else return (handle_', "")
- else ioError e
+ let r = if isEOFError e
+ then if not (isEmptyBuffer buf)
+ then "\r"
+ else ""
+ else
+ throw (augmentIOError e "hGetContents" h)
+
+ return (handle_', r)
)
-- ensure we have some characters in the buffer
)
-- ensure we have some characters in the buffer