[Haskell-cafe] Data.Text.IO.hGetContents problem on windows

David Virebayre dav.vire+haskell at gmail.com
Tue Sep 20 08:54:57 CEST 2011

Re-bonjour Café, Bryan,

> I have a program that works fine on linux, but doesn't on windows.
> Is there something I'm doing wrong ?

Checking the source code for Data.Text.IO.hGetContents, I see that the
only time hFileSize is used is in chooseGoodBuffering when the
buffering is in block mode, so I have a workaround: I just set the
buffering in line mode, which forks for my case.

The documentation for hFileSize says
"For a handle hdl which attached to a physical file, hFileSize hdl
returns the size of that file in 8-bit bytes."

So chooseGoodBuffering should check if the handle is a physical file
before trying to optimize the buffer size, right ?

However, I'm not sure how to check if the handle is a physical file.
hIsTerminalDevice wouldn't help here, I guess.
hIsSeekable give this on windows : <socket: 1860>: hIsSeekable:
invalid argument (Bad file descriptor)

Maybe the solution would be to try hFileSize, and set a default
buffering if an exception is caught ?

> David.
> The source code of the part that fails is as follows:
> -- Execute a command on a distant server using the rexec protocol.
> rexec :: HostName     -- server to connect to
>      -> Text         -- user
>      -> Text         -- password
>      -> TextEncoding -- server's text encoding
>      -> Text         -- command to execute
>      -> IO (Maybe Text)
> rexec !ip !ru !rp !enc cmd = handle rexec_error $ do
>  hdl <- connectTo ip (PortNumber 512)
>  let end_param = T.singleton (chr 0)
>     ctrl_string = T.concat [
>         "0", end_param,
>         ru, end_param,
>         rp, end_param,
>         cmd, end_param
>       ]
>  hSetEncoding hdl enc
>  TIO.hPutStr hdl ctrl_string
>  -- make sure the control string is sent.
>  hFlush hdl
>  -- 1st char read is actually a error code which we ignore for now
>  hGetChar hdl
>  !res <- TIO.hGetContents hdl
>  hClose hdl
>  return (Just res)
> rexec_error :: SomeException -> IO (Maybe Text)
> rexec_error err = do
>  putStrLn $ show err
>  return Nothing

More information about the Haskell-Cafe mailing list