Data.Text.IO.hGetContents problem on windows
Bonjour Café, bonjour Bryan I have a program that works fine on linux, but doesn't on windows. On windows XP with the latest Haskell platform, I get: <socket: 1860>: hFileSize: invalid argument (Bad file descriptor) I think the problem is with hGetContents from Data.Text.IO, but my google-fu failed to help me find any information. Is there something I'm doing wrong ? 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
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.
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
participants (1)
-
David Virebayre