-- License : BSD-style (see the file libraries/base/LICENSE)
--
-- Maintainer : libraries@haskell.org
--- Stability : provisional
+-- Stability : stable
-- Portability : portable
--
-- The standard IO library.
-- * Operations on handles
- -- ** Determining the size of a file
+ -- ** Determining and changing the size of a file
hFileSize, -- :: Handle -> IO Integer
+#ifdef __GLASGOW_HASKELL__
+ hSetFileSize, -- :: Handle -> Integer -> IO ()
+#endif
-- ** Detecting the end of input
-- ** Terminal operations
-#if !defined(__HUGS__) && !defined(__NHC__)
+#if !defined(__NHC__)
hIsTerminalDevice, -- :: Handle -> IO Bool
hSetEcho, -- :: Handle -> Bool -> IO ()
-- * Binary input and output
-#if !defined(__NHC__)
openBinaryFile, -- :: FilePath -> IOMode -> IO Handle
-#endif
-
-#if !defined(__HUGS__) && !defined(__NHC__)
hSetBinaryMode, -- :: Handle -> Bool -> IO ()
+#if !defined(__NHC__)
hPutBuf, -- :: Handle -> Ptr a -> Int -> IO ()
hGetBuf, -- :: Handle -> Ptr a -> Int -> IO Int
+#endif
+#if !defined(__NHC__) && !defined(__HUGS__)
hPutBufNonBlocking, -- :: Handle -> Ptr a -> Int -> IO Int
hGetBufNonBlocking, -- :: Handle -> Ptr a -> Int -> IO Int
#endif
+ -- * Temporary files
+
+#ifdef __GLASGOW_HASKELL__
+ openTempFile,
+ openBinaryTempFile,
+#endif
+
module System.IO.Error,
) where
#ifdef __HUGS__
import Hugs.IO
import Hugs.IOExts
+import Hugs.IORef
+import Hugs.Prelude ( throw, Exception(NonTermination) )
+import System.IO.Unsafe ( unsafeInterleaveIO )
#endif
#ifdef __NHC__
, hGetContents -- :: Handle -> IO [Char]
, hPutChar -- :: Handle -> Char -> IO ()
, hPutStr -- :: Handle -> [Char] -> IO ()
+ , hPutStrLn -- :: Handle -> [Char] -> IO ()
+ , hPrint -- :: Handle -> [Char] -> IO ()
+ , hReady -- :: Handle -> [Char] -> IO ()
, hIsOpen, hIsClosed -- :: Handle -> IO Bool
, hIsReadable, hIsWritable -- :: Handle -> IO Bool
, hIsSeekable -- :: Handle -> IO Bool
-- -----------------------------------------------------------------------------
-- Standard IO
-#ifndef __HUGS__
+#ifdef __GLASGOW_HASKELL__
-- | Write a character to the standard output device
-- (same as 'hPutChar' 'stdout').
putStr :: String -> IO ()
putStr s = hPutStr stdout s
--- | The same as 'putStrLn', but adds a newline character.
+-- | The same as 'putStr', but adds a newline character.
putStrLn :: String -> IO ()
putStrLn s = do putStr s
[x] -> return x
[] -> ioError (userError "Prelude.readIO: no parse")
_ -> ioError (userError "Prelude.readIO: ambiguous parse")
-#endif /* __HUGS__ */
+#endif /* __GLASGOW_HASKELL__ */
+#ifndef __NHC__
-- | Computation 'hReady' @hdl@ indicates whether at least one item is
-- available for input from handle @hdl@.
--
hPrint :: Show a => Handle -> a -> IO ()
hPrint hdl = hPutStrLn hdl . show
+#endif /* !__NHC__ */
-- ---------------------------------------------------------------------------
-- fixIO
-#ifdef __GLASGOW_HASKELL__
-fixIO :: (a -> IO a) -> IO a
-fixIO m = stToIO (fixST (ioToST . m))
+#if defined(__GLASGOW_HASKELL__) || defined(__HUGS__)
+fixIO :: (a -> IO a) -> IO a
+fixIO k = do
+ ref <- newIORef (throw NonTermination)
+ ans <- unsafeInterleaveIO (readIORef ref)
+ result <- k ans
+ writeIORef ref result
+ return result
+
+-- NOTE: we do our own explicit black holing here, because GHC's lazy
+-- blackholing isn't enough. In an infinite loop, GHC may run the IO
+-- computation a few times before it notices the loop, which is wrong.
+#endif
+
+#if defined(__NHC__)
+-- Assume a unix platform, where text and binary I/O are identical.
+openBinaryFile = openFile
+hSetBinaryMode _ _ = return ()
#endif
-- $locking