    {-# LANGUAGE CPP         #-}
    {-# LANGUAGE Trustworthy #-}
    module Lukko.Internal.HandleToFD (ghcHandleToFd) where

    import qualified GHC.IO.FD as GHC (FD (..))
    import           System.IO (Handle)

    #if MIN_VERSION_base(4,10,0)
    import qualified GHC.IO.Handle.FD as GHC (handleToFd)
    #else
    import Control.Concurrent.MVar (readMVar)
    import Data.Typeable           (cast)
    import GHC.IO.Exception
    import GHC.IO.Handle.Internals
    import GHC.IO.Handle.Types
    #endif

    ghcHandleToFd :: Handle -> IO GHC.FD
    #if MIN_VERSION_base(4,10,0)
    ghcHandleToFd :: Handle -> IO FD
    ghcHandleToFd = Handle -> IO FD
    GHC.handleToFd
    #else
    ghcHandleToFd h = case h of
        FileHandle _ mv -> do
          Handle__{haDevice = dev} <- readMVar mv
          case cast dev of
              Just fd -> return fd
              Nothing -> throwErr "not a file descriptor"
        DuplexHandle{} -> throwErr "not a file handle"
      where
        throwErr msg = ioException $ IOError (Just h)
          InappropriateType "handleToFd" msg Nothing Nothing
    #endif