I'd like to open a pseudo-tty and use the resulting slave terminal to connect to stdin/stdout on a subprocess. openPseudoTerminal gives me an IO (System.Posix.Types.Fd, System.Posix.Types.Fd), which I sought to translate into a pair of handles using fdToHandle in GHC.IO.Handle.Fd (GHC specific, but I couldn't find another such function). However, I get the following:
liftA (fdToHandle *** fdToHandle) openPseudoTerminal
Couldn't match type `System.Posix.Types.Fd'
with `System.Posix.Internals.FD'
Any ideas how I convert between these two (presumably similar) things?
For bonus points, this will give me an IO (IO Handle, IO Handle) - is there a neat way to convert it to an IO (Handle, Handle)?
openPseudoTerminal is in the unix package, which also provides an fdToHandle with the appropriate type in System.Posix.IO.
I'll throw in the best one-liner I have come up with so far, to deal with the pair of IO Handles:
getHandles :: IO (Handle, Handle)
getHandles =
openPseudoTerminal >>= uncurry ap . (fmap (,) . fdToHandle *** fdToHandle)
or:
getHandles =
openPseudoTerminal >>= uncurry (ap . fmap (,)) . join (***) fdToHandle
You can ask GHCI for information about these types --
>> :i FD
type FD = Foreign.C.Types.CInt
>> :i Fd
newtype Fd = Fd Foreign.C.Types.CInt
so they are essentially identical, except that one is a newtype and the other is a type. So the conversion functions are (I recommend choosing better names)
convert :: FD -> Fd
convert = Fd
convert' :: Fd -> FD
convert' (Fd x) = x
RE your question about converting from IO (IO Handle, IO Handle) to IO (Handle,Handle) you could do this explicitly
flatten :: IO (IO a, IO a) -> IO (a,a)
flatten x = do
(a,b) <- x
a' <- a
b' <- b
return (a', b')
but a better way would be to avoid creatign the IO (IO Handle, IO Handle) in the first place. Since your types are
openPseudoTerminal :: IO (Fd, Fd)
fdToHandle :: FD -> IO Handle
you could do
getHandles :: IO (Handle, Handle)
getHandles = do
(Fd a, Fd b) <- openPseudoTerminal
a' <- fdToHandle a
b' <- fdToHandle b
return (a', b')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With