How does hWaitForInput work?

This bit of code gets characters from stdin

and converts them to a string. There hWaitForInput

is a timeout on the input entered with . I have enabled the function tryIOError

to capture isEOFError

. This time works correctly when the program is running and no login has been made, i.e. Waiting for input. However, once a character is entered, it no longer expires. Regardless of the input timeout.

-- get string from stdin
getFrmStdIn :: Int -> IO String
getFrmStdIn timeout = do
  inAvail <- tryIOError $ hWaitForInput stdin timeout
  let tOut = either (const False) id inAvail
  if isLeft inAvail
    then return []
  else
    if not tOut
      then die "00 timed out"
    else
      (:) <$> hGetChar stdin <*> getFrmStdIn timeout

      

+4


source to share


2 answers


What version of OS and GHC are you using?



AFAIK with resent versions GHC

hWaitForInput

it does not work at all on linux when the timeout is not 0. On windows, the entire I / O subsystem is "a little short" .

+1


source


However, once a character is entered, it no longer expires. It doesn't matter how long it takes to wait for input.

This is how it should work according to the docs :

The calculation of hWaitForInput hdl t waits until input is available for the hdl handle. It returns True as soon as input is available on hdl, or False if input is not available for t milliseconds.



Here is a use case hWaitForInput

where it will wait five seconds and then check if there are any characters in stdin

. If not, it will say "Timeout reached". Otherwise it will wait for the user to hit enter ( hGetLine

checks for the end of the line) and the hGetLine

user on the line:

main :: IO ()
main =
  hWaitForInput stdin 5000 >>= \inputIsAvailable ->
    if inputIsAvailable
      then hGetLine stdin >>= \input -> putStrLn $ "There is input: " ++ input
      else putStrLn "Timeout reached"

      

0


source







All Articles