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 Handle
s:
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