@@ -157,11 +157,21 @@ import Foreign.Ptr (Ptr)
157import Foreign.Storable (peek, peekByteOff, sizeOf)
157import Foreign.Storable (peek, peekByteOff, sizeOf)
158import GHC.IO.Device (IODeviceType(Stream))
158import GHC.IO.Device (IODeviceType(Stream))
159import GHC.IO.FD (fdFD, mkFD)
159import GHC.IO.FD (fdFD, mkFD)
160−import GHC.IO.Handle.FD (mkHandleFromFD, handleToFd)
160+import GHC.IO.Handle.FD (mkHandleFromFD)
161import Streamly (SerialT)
161import Streamly (SerialT)
162import Streamly.Internal.Data.Parser (Parser)
162import Streamly.Internal.Data.Parser (Parser)
163import Streamly.Internal.Memory.Array.Types (Array(..))
163import Streamly.Internal.Memory.Array.Types (Array(..))
164import System.IO (Handle, hClose, IOMode(ReadMode))
164import System.IO (Handle, hClose, IOMode(ReadMode))
165+#if !MIN_VERSION_base(4,10,0)
166+import Control.Concurrent.MVar (readMVar)
167+import Data.Typeable (cast)
168+import GHC.IO.Exception (IOException(..), IOErrorType(..), ioException)
169+import GHC.IO.FD (FD)
170+import GHC.IO.Handle.Types (Handle__(..), Handle(FileHandle, DuplexHandle))
172+import GHC.IO.Handle.FD (handleToFd)
166import qualified Data.IntMap.Lazy as Map
176import qualified Data.IntMap.Lazy as Map
167import qualified Streamly.Internal.Data.Fold as FL
177import qualified Streamly.Internal.Data.Fold as FL
@@ -543,6 +553,24 @@ foreign import ccall unsafe
543utf8ToString :: Array Word8 -> String
553utf8ToString :: Array Word8 -> String
544utf8ToString = runIdentity . S.toList . U.decodeUtf8 . A.toStream
554utf8ToString = runIdentity . S.toList . U.decodeUtf8 . A.toStream
556+#if !MIN_VERSION_base(4,10,0)
557+-- | Turn an existing Handle into a file descriptor. This function throws an
558+-- IOError if the Handle does not reference a file descriptor.
559+handleToFd :: Handle -> IO FD
560+handleToFd h = case h of
561+ FileHandle _ mv -> do
562+ Handle__{haDevice = dev} <- readMVar mv
564+ Just fd -> return fd
565+ Nothing -> throwErr "not a file descriptor"
566+ DuplexHandle{} -> throwErr "not a file handle"
570+ throwErr msg = ioException $ IOError (Just h)
571+ InappropriateType "handleToFd" msg Nothing Nothing
546-- | Given a 'Config' and a @path@ supplied as a UTF-8 encoded byte array, add
574-- | Given a 'Config' and a @path@ supplied as a UTF-8 encoded byte array, add
547-- the path to the list of paths being monitored by the given watch 'Handle'.
575-- the path to the list of paths being monitored by the given watch 'Handle'.
548-- Returns a "watch descriptor" which is used as an idenitfier in the events
576-- Returns a "watch descriptor" which is used as an idenitfier in the events