Fix hWaitForInput
[ghc-base.git] / GHC / IO / Handle / Text.hs
index 2dd86df..ed3a106 100644 (file)
@@ -78,22 +78,32 @@ import GHC.List
 hWaitForInput :: Handle -> Int -> IO Bool
 hWaitForInput h msecs = do
   wantReadableHandle_ "hWaitForInput" h $ \ handle_@Handle__{..} -> do
-  buf <- readIORef haCharBuffer
+  cbuf <- readIORef haCharBuffer
 
-  if not (isEmptyBuffer buf)
-        then return True
-        else do
+  if not (isEmptyBuffer cbuf) then return True else do
 
   if msecs < 0 
-        then do buf' <- readTextDevice handle_ buf
-                writeIORef haCharBuffer buf'
+        then do cbuf' <- readTextDevice handle_ cbuf
+                writeIORef haCharBuffer cbuf'
                 return True
-        else do r <- IODevice.ready haDevice False{-read-} msecs
+        else do
+               -- there might be bytes in the byte buffer waiting to be decoded
+               cbuf' <- readTextDeviceNonBlocking handle_ cbuf
+               writeIORef haCharBuffer cbuf'
+
+               if not (isEmptyBuffer cbuf') then return True else do
+
+                r <- IODevice.ready haDevice False{-read-} msecs
                 if r then do -- Call hLookAhead' to throw an EOF
-                                  -- exception if appropriate
-                                  hLookAhead_ handle_
-                                  return True
-                          else return False
+                             -- exception if appropriate
+                             _ <- hLookAhead_ handle_
+                             return True
+                     else return False
+                -- XXX we should only return when there are full characters
+                -- not when there are only bytes.  That would mean looping
+                -- and re-running IODevice.ready if we don't have any full
+                -- characters; but we don't know how long we've waited
+                -- so far.
 
 -- ---------------------------------------------------------------------------
 -- hGetChar
@@ -394,7 +404,7 @@ getSomeCharacters handle_@Handle__{..} buf@Buffer{..} =
                  -- if we're about to call readTextDevice, otherwise it
                  -- would mess up flushCharBuffer.
                  -- See [note Buffer Flushing], GHC.IO.Handle.Types
-                 writeCharBuf bufRaw 0 '\r'
+                 _ <- writeCharBuf bufRaw 0 '\r'
                  let buf' = buf{ bufL=0, bufR=1 }
                  readTextDevice handle_ buf'
          else do
@@ -527,7 +537,7 @@ writeBlocks hdl line_buffered nl
   let
    shoveString :: Int -> [Char] -> IO ()
    shoveString !n [] = do
-        commitBuffer hdl raw len n False{-no flush-} True{-release-}
+        _ <- commitBuffer hdl raw len n False{-no flush-} True{-release-}
         return ()
    shoveString !n (c:cs)
      -- n+1 so we have enough room to write '\r\n' if necessary
@@ -646,7 +656,9 @@ commitBuffer' raw sz@(I# _) count@(I# _) flush release
                         -- otherwise, we have to flush the new data too,
                         -- and start with a fresh buffer
                         else do
-                          flushWriteBuffer_ handle_ this_buf
+                          -- We're aren't going to use this buffer again
+                          -- so we ignore the result of flushWriteBuffer_
+                          _ <- flushWriteBuffer_ handle_ this_buf
                           writeIORef ref flushed_buf
                             -- if the sizes were different, then allocate
                             -- a new buffer of the correct size.
@@ -678,6 +690,9 @@ commitBuffer' raw sz@(I# _) count@(I# _) flush release
 -- 'hPutBuf' ignores any text encoding that applies to the 'Handle',
 -- writing the bytes directly to the underlying file or device.
 --
+-- 'hPutBuf' ignores the prevailing 'TextEncoding' and
+-- 'NewlineMode' on the 'Handle', and writes bytes directly.
+--
 -- This operation may fail with:
 --
 --  * 'ResourceVanished' if the handle is a pipe or socket, and the
@@ -689,7 +704,8 @@ hPutBuf :: Handle                       -- handle to write to
         -> Ptr a                        -- address of buffer
         -> Int                          -- number of bytes of data in buffer
         -> IO ()
-hPutBuf h ptr count = do hPutBuf' h ptr count True; return ()
+hPutBuf h ptr count = do _ <- hPutBuf' h ptr count True
+                         return ()
 
 hPutBufNonBlocking
         :: Handle                       -- handle to write to
@@ -742,9 +758,9 @@ bufWrite h_@Handle__{..} ptr count can_block =
 
         -- else, we have to flush
         else do debugIO "hPutBuf: flushing first"
-                Buffered.flushWriteBuffer haDevice old_buf
+                old_buf' <- Buffered.flushWriteBuffer haDevice old_buf
                         -- TODO: we should do a non-blocking flush here
-                writeIORef haByteBuffer old_buf{bufL=0,bufR=0}
+                writeIORef haByteBuffer old_buf'
                 -- if we can fit in the buffer, then just loop  
                 if count < size
                    then bufWrite h_ ptr count can_block
@@ -781,6 +797,8 @@ writeChunkNonBlocking h_@Handle__{..} ptr bytes
 -- If the handle is a pipe or socket, and the writing end
 -- is closed, 'hGetBuf' will behave as if EOF was reached.
 --
+-- 'hGetBuf' ignores the prevailing 'TextEncoding' and 'NewlineMode'
+-- on the 'Handle', and reads bytes directly.
 
 hGetBuf :: Handle -> Ptr a -> Int -> IO Int
 hGetBuf h ptr count
@@ -865,6 +883,9 @@ readChunk h_@Handle__{..} ptr bytes
 -- If the handle is a pipe or socket, and the writing end
 -- is closed, 'hGetBufNonBlocking' will behave as if EOF was reached.
 --
+-- 'hGetBufNonBlocking' ignores the prevailing 'TextEncoding' and
+-- 'NewlineMode' on the 'Handle', and reads bytes directly.
+
 hGetBufNonBlocking :: Handle -> Ptr a -> Int -> IO Int
 hGetBufNonBlocking h ptr count
   | count == 0 = return 0
@@ -936,16 +957,16 @@ readChunkNonBlocking h_@Handle__{..} ptr bytes
 -- memcpy wrappers
 
 copyToRawBuffer :: RawBuffer e -> Int -> Ptr e -> Int -> IO ()
-copyToRawBuffer raw off ptr bytes = do
+copyToRawBuffer raw off ptr bytes =
  withRawBuffer raw $ \praw ->
-   memcpy (praw `plusPtr` off) ptr (fromIntegral bytes)
- return ()
+   do _ <- memcpy (praw `plusPtr` off) ptr (fromIntegral bytes)
+      return ()
 
 copyFromRawBuffer :: Ptr e -> RawBuffer e -> Int -> Int -> IO ()
-copyFromRawBuffer ptr raw off bytes = do
+copyFromRawBuffer ptr raw off bytes =
  withRawBuffer raw $ \praw ->
-   memcpy ptr (praw `plusPtr` off) (fromIntegral bytes)
- return ()
+   do _ <- memcpy ptr (praw `plusPtr` off) (fromIntegral bytes)
+      return ()
 
 foreign import ccall unsafe "memcpy"
    memcpy :: Ptr a -> Ptr a -> CSize -> IO (Ptr ())