X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;ds=sidebyside;f=Control%2FException.hs;h=e4e037eaa4f6345f0a6149ebd38d7800006a4737;hb=ed813264145aa7d96c44375c8d92c93e3b1a4539;hp=7d66da84a41bce98d95e358274952500390986e6;hpb=f6c8204a3d0865ffc39f4451320d46d1571c1f66;p=haskell-directory.git diff --git a/Control/Exception.hs b/Control/Exception.hs index 7d66da8..e4e037e 100644 --- a/Control/Exception.hs +++ b/Control/Exception.hs @@ -105,20 +105,27 @@ module Control.Exception ( bracket_, -- :: IO a -> IO b -> IO c -> IO () finally, -- :: IO a -> IO b -> IO a - + +#ifdef __GLASGOW_HASKELL__ + setUncaughtExceptionHandler, -- :: (Exception -> IO ()) -> IO () + getUncaughtExceptionHandler -- :: IO (Exception -> IO ()) +#endif ) where #ifdef __GLASGOW_HASKELL__ import GHC.Base ( assert ) import GHC.Exception as ExceptionBase hiding (catch) import GHC.Conc ( throwTo, ThreadId ) -import GHC.IOBase ( IO(..) ) +import GHC.IOBase ( IO(..), IORef(..), newIORef, readIORef, writeIORef ) +import GHC.Handle ( stdout, hFlush ) #endif #ifdef __HUGS__ import Hugs.Exception as ExceptionBase #endif +import Foreign.C.String ( CString, withCStringLen ) + import Prelude hiding ( catch ) import System.IO.Error hiding ( catch, try ) import System.IO.Unsafe (unsafePerformIO) @@ -488,7 +495,7 @@ Similar arguments apply for other interruptible operations like #ifdef __HADDOCK__ -- | If the first argument evaluates to 'True', then the result is the --- second argument. Otherwise an 'Assertion' exception is raised, +-- second argument. Otherwise an 'AssertionFailed' exception is raised, -- containing a 'String' with the source file and line number of the -- call to assert. -- @@ -505,3 +512,28 @@ assert :: Bool -> a -> a assert True x = x assert False _ = throw (AssertionFailed "") #endif + + +#ifdef __GLASGOW_HASKELL__ +{-# NOINLINE uncaughtExceptionHandler #-} +uncaughtExceptionHandler :: IORef (Exception -> IO ()) +uncaughtExceptionHandler = unsafePerformIO (newIORef defaultHandler) + where + defaultHandler :: Exception -> IO () + defaultHandler ex = do + (hFlush stdout) `catchException` (\ _ -> return ()) + let msg = case ex of + Deadlock -> "no threads to run: infinite loop or deadlock?" + ErrorCall s -> s + other -> showsPrec 0 other "\n" + withCStringLen ("Fail: "++msg) $ \(cstr,len) -> writeErrString cstr len + +foreign import ccall unsafe "writeErrString__" + writeErrString :: CString -> Int -> IO () + +setUncaughtExceptionHandler :: (Exception -> IO ()) -> IO () +setUncaughtExceptionHandler = writeIORef uncaughtExceptionHandler + +getUncaughtExceptionHandler :: IO (Exception -> IO ()) +getUncaughtExceptionHandler = readIORef uncaughtExceptionHandler +#endif