Description
This issue posting picks up a discussion, involving @bgamari and @Mistuke, originating in UnkindPartition/ansi-terminal#114.
Absent GHC 9 series option --io-manager=native
, System.Win32.Types.withHandleToHANDLE
returns the (Windows) HANDLE
of a (GHC) Handle
, irrespective of whether the Handle
was a 'console' Handle
(like stdout
) or a 'file' Handle
.
Now, with --io-manager=native
set, System.Win32.Types.withHandleToHANDLENative
uses GHC.IO.Handle.Windows.handleToHANDLE
and that latter function will not return the referenced HANDLE
if Handle
is not a 'file' Handle
.
-- | Turn an existing Handle into a Win32 HANDLE. This function throws an
-- IOError if the Handle does not reference a HANDLE
handleToHANDLE :: Handle -> IO Win.HANDLE
handleToHANDLE h = case h of
FileHandle _ mv -> do
Handle__{haDevice = dev} <- readMVar mv
case (cast dev :: Maybe (Win.Io Win.NativeHandle)) of
Just hwnd -> return $ Win.toHANDLE hwnd
Nothing -> throwErr "not a file HANDLE" -- <<< Throws this error if h is stdout :: Handle
DuplexHandle{} -> throwErr "not a file handle"
where
throwErr msg = ioException $ IOError (Just h)
InappropriateType "handleToHANDLE" msg Nothing Nothing
This causes a problem on ansi-terminal
because it assumes that if a Handle
('console' or 'file') references a HANDLE
, withHandleToHANDLE
will return that HANDLE
. (ansi-terminal
then goes on to examine what sort of HANDLE
has been referenced, using the Windows API and packages such as mintty
.)
My personal preference is that withHandleToHANDLE
should do what it currently does when --io-manager=native
is not set (irrespective of the setting), and that if a more specific function is required that effectively 'filters out' a non-'file' Handle
, that should be a distinct function.
As an aside, the current Haddock documentation for System.Win32.Types.withHandleToHANDLE
does not identify the change in behaviour if --io-manager=native
is set.
Activity
Mistuke commentedon Nov 15, 2021
Thank you! I'm currently away but will fix it this weekend. Is there a testsuite I can run too?
mpilgrem commentedon Nov 15, 2021
@Mistuke, by testsuite you may mean something more sophisticated than this, but a simple program:
should compile (with
ghc-options
-with-rtsopts=--io-manager=native
) and execute without error. (When run, it should just clear the screen.)It will need a dependency on package
ansi-terminal
. The version of theWin32
package will need to be specified to be at leastWin32-2.13.1
; a requirement ofmintty-0.1.3
. I use stack, withstack.yaml
:Mistuke commentedon Nov 19, 2021
Thanks! Working on the fix now
mpilgrem commentedon Nov 19, 2021
I have had some success with:
Mistuke commentedon Nov 20, 2021
@mpilgrem the changes in #192 fix things for me, if you can confirm I'll release the package and do the backports.
mpilgrem commentedon Nov 20, 2021
@Mistuke , this is what I have done to test successfully on Windows 11 (Version 10.0.22000.318) and using terminal software (Microsoft) Windows Terminal version 1.11.2921.0:
-with-rtsopts=--io-manager=native
and withstack.yaml
(GHC 9.0.1):-with-rtsopts=--io-manager=native
and withstack.yaml
(GHC 9.2.1):ansi-terminal-example
example (test) applicaton with with/without-with-rtsopts=--io-manager=native
and withstack.yaml
(GHC 9.2.1):Mistuke commentedon Nov 20, 2021
@mpilgrem awesome, thanks for confirming! I'll release and make the backports tomorrow morning.