2 % (c) The AQUA Project, Glasgow University, 1994-1998
4 \section[IO]{Module @IO@}
6 Implementation of the standard Haskell IO interface, see
7 @http://haskell.org/onlinelibrary/io.html@ for the official
11 {-# OPTIONS -fno-implicit-prelude -#include "cbits/stgio.h" #-}
14 Handle, -- abstract, instance of: Eq, Show.
15 HandlePosn(..), -- abstract, instance of: Eq, Show.
17 IOMode(ReadMode,WriteMode,AppendMode,ReadWriteMode),
18 BufferMode(NoBuffering,LineBuffering,BlockBuffering),
19 SeekMode(AbsoluteSeek,RelativeSeek,SeekFromEnd),
21 stdin, stdout, stderr, -- :: Handle
23 openFile, -- :: FilePath -> IOMode -> IO Handle
24 hClose, -- :: Handle -> IO ()
25 hFileSize, -- :: Handle -> IO Integer
26 hIsEOF, -- :: Handle -> IO Bool
29 hSetBuffering, -- :: Handle -> BufferMode -> IO ()
30 hGetBuffering, -- :: Handle -> IO BufferMode
31 hFlush, -- :: Handle -> IO ()
32 hGetPosn, -- :: Handle -> IO HandlePosn
33 hSetPosn, -- :: Handle -> HandlePosn -> IO ()
34 hSeek, -- :: Handle -> SeekMode -> Integer -> IO ()
35 hWaitForInput, -- :: Handle -> Int -> IO Bool
36 hReady, -- :: Handle -> IO Bool
37 hGetChar, -- :: Handle -> IO Char
38 hGetLine, -- :: Handle -> IO [Char]
39 hLookAhead, -- :: Handle -> IO Char
40 hGetContents, -- :: Handle -> IO [Char]
41 hPutChar, -- :: Handle -> Char -> IO ()
42 hPutStr, -- :: Handle -> [Char] -> IO ()
43 hPutStrLn, -- :: Handle -> [Char] -> IO ()
44 hPrint, -- :: Show a => Handle -> a -> IO ()
45 hIsOpen, hIsClosed, -- :: Handle -> IO Bool
46 hIsReadable, hIsWritable, -- :: Handle -> IO Bool
47 hIsSeekable, -- :: Handle -> IO Bool
49 isAlreadyExistsError, isDoesNotExistError, -- :: IOError -> Bool
50 isAlreadyInUseError, isFullError,
51 isEOFError, isIllegalOperation,
52 isPermissionError, isUserError,
54 ioeGetErrorString, -- :: IOError -> String
55 ioeGetHandle, -- :: IOError -> Maybe Handle
56 ioeGetFileName, -- :: IOError -> Maybe FilePath
58 try, -- :: IO a -> IO (Either IOError a)
59 bracket, -- :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c
60 bracket_, -- :: IO a -> (a -> IO b) -> IO c -> IO c
62 -- Non-standard extension (but will hopefully become standard with 1.5) is
63 -- to export the Prelude io functions via IO (in addition to exporting them
64 -- from the prelude...for now.)
66 FilePath, -- :: String
68 ioError, -- :: IOError -> IO a
69 userError, -- :: String -> IOError
70 catch, -- :: IO a -> (IOError -> IO a) -> IO a
71 interact, -- :: (String -> String) -> IO ()
73 putChar, -- :: Char -> IO ()
74 putStr, -- :: String -> IO ()
75 putStrLn, -- :: String -> IO ()
76 print, -- :: Show a => a -> IO ()
77 getChar, -- :: IO Char
78 getLine, -- :: IO String
79 getContents, -- :: IO String
80 readFile, -- :: FilePath -> IO String
81 writeFile, -- :: FilePath -> String -> IO ()
82 appendFile, -- :: FilePath -> String -> IO ()
83 readIO, -- :: Read a => String -> IO a
84 readLn, -- :: Read a => IO a
102 import PrelHandle -- much of the real stuff is in here
104 import PrelRead ( readParen, Read(..), reads, lex,
108 import PrelMaybe ( Either(..), Maybe(..) )
109 import PrelAddr ( Addr(..), nullAddr )
110 import PrelByteArr ( ByteArray )
111 import PrelPack ( unpackNBytesAccST )
112 import PrelException ( ioError, catch )
115 #ifndef __PARALLEL_HASKELL__
116 import PrelForeign ( ForeignObj )
119 import Char ( ord, chr )
121 #endif /* ndef __HUGS__ */
125 %*********************************************************
127 \subsection{Simple input operations}
129 %*********************************************************
131 Computation @hReady hdl@ indicates whether at least
132 one item is available for input from handle {\em hdl}.
134 @hWaitForInput@ is the generalisation, wait for \tr{n} milliseconds
135 before deciding whether the Handle has run dry or not.
137 If @hWaitForInput@ finds anything in the Handle's buffer, it immediately returns.
138 If not, it tries to read from the underlying OS handle. Notice that
139 for buffered Handles connected to terminals this means waiting until a complete
143 hReady :: Handle -> IO Bool
144 hReady h = hWaitForInput h 0
146 hWaitForInput :: Handle -> Int -> IO Bool
147 hWaitForInput handle msecs =
148 wantReadableHandle "hWaitForInput" handle $ \ handle_ -> do
149 rc <- inputReady (haFO__ handle_) (msecs::Int) -- ConcHask: SAFE, won't block
153 _ -> constructErrorAndFail "hWaitForInput"
156 @hGetChar hdl@ reads the next character from handle @hdl@,
157 blocking until a character is available.
160 hGetChar :: Handle -> IO Char
162 c <- mayBlockRead "hGetChar" handle fileGetc
166 If EOF is reached before EOL is encountered, ignore the
167 EOF and return the partial line. Next attempt at calling
168 hGetLine on the handle will yield an EOF IO exception though.
170 hGetLine :: Handle -> IO String
184 if isEOFError err then
196 @hLookahead hdl@ returns the next character from handle @hdl@
197 without removing it from the input buffer, blocking until a
198 character is available.
201 hLookAhead :: Handle -> IO Char
202 hLookAhead handle = do
203 rc <- mayBlockRead "hLookAhead" handle fileLookAhead
208 %*********************************************************
210 \subsection{Getting the entire contents of a handle}
212 %*********************************************************
214 @hGetContents hdl@ returns the list of characters corresponding
215 to the unread portion of the channel or file managed by @hdl@,
216 which is made semi-closed.
219 hGetContents :: Handle -> IO String
220 hGetContents handle =
221 -- can't use wantReadableHandle here, because we want to side effect
223 withHandle handle $ \ handle_ -> do
224 case haType__ handle_ of
225 ErrorHandle theError -> ioError theError
226 ClosedHandle -> ioe_closedHandle "hGetContents" handle
227 SemiClosedHandle -> ioe_closedHandle "hGetContents" handle
228 AppendHandle -> ioError not_readable_error
229 WriteHandle -> ioError not_readable_error
232 To avoid introducing an extra layer of buffering here,
233 we provide three lazy read methods, based on character,
234 line, and block buffering.
236 let handle_' = handle_{ haType__ = SemiClosedHandle }
237 case (haBufferMode__ handle_) of
239 str <- unsafeInterleaveIO (lazyReadLine handle (haFO__ handle_))
240 return (handle_', str)
241 BlockBuffering _ -> do
242 str <- unsafeInterleaveIO (lazyReadBlock handle (haFO__ handle_))
243 return (handle_', str)
245 str <- unsafeInterleaveIO (lazyReadChar handle (haFO__ handle_))
246 return (handle_', str)
249 IOError (Just handle) IllegalOperation "hGetContents"
250 ("handle is not open for reading")
253 Note that someone may close the semi-closed handle (or change its buffering),
254 so each these lazy read functions are pulled on, they have to check whether
255 the handle has indeed been closed.
258 #ifndef __PARALLEL_HASKELL__
259 lazyReadBlock :: Handle -> ForeignObj -> IO String
260 lazyReadLine :: Handle -> ForeignObj -> IO String
261 lazyReadChar :: Handle -> ForeignObj -> IO String
263 lazyReadBlock :: Handle -> Addr -> IO String
264 lazyReadLine :: Handle -> Addr -> IO String
265 lazyReadChar :: Handle -> Addr -> IO String
268 lazyReadBlock handle fo = do
269 buf <- getBufStart fo 0
270 bytes <- mayBlock fo (readBlock fo) -- ConcHask: UNSAFE, may block.
272 -3 -> -- buffering has been turned off, use lazyReadChar instead
273 lazyReadChar handle fo
275 -1 -> -- an error occurred, close the handle
276 withHandle handle $ \ handle_ -> do
277 closeFile (haFO__ handle_) 0{-don't bother flushing-} -- ConcHask: SAFE, won't block.
278 return (handle_ { haType__ = ClosedHandle,
279 haFO__ = nullFile__ },
282 more <- unsafeInterleaveIO (lazyReadBlock handle fo)
283 stToIO (unpackNBytesAccST buf bytes more)
285 lazyReadLine handle fo = do
286 bytes <- mayBlock fo (readLine fo) -- ConcHask: UNSAFE, may block.
288 -3 -> -- buffering has been turned off, use lazyReadChar instead
289 lazyReadChar handle fo
290 -2 -> return "" -- handle closed by someone else, stop reading.
291 -1 -> -- an error occurred, close the handle
292 withHandle handle $ \ handle_ -> do
293 closeFile (haFO__ handle_) 0{- don't bother flushing-} -- ConcHask: SAFE, won't block
294 return (handle_ { haType__ = ClosedHandle,
295 haFO__ = nullFile__ },
298 more <- unsafeInterleaveIO (lazyReadLine handle fo)
299 buf <- getBufStart fo bytes -- ConcHask: won't block
300 stToIO (unpackNBytesAccST buf bytes more)
302 lazyReadChar handle fo = do
303 char <- mayBlock fo (readChar fo) -- ConcHask: UNSAFE, may block.
305 -4 -> -- buffering is now block-buffered, use lazyReadBlock instead
306 lazyReadBlock handle fo
308 -3 -> -- buffering is now line-buffered, use lazyReadLine instead
309 lazyReadLine handle fo
311 -1 -> -- error, silently close handle.
312 withHandle handle $ \ handle_ -> do
313 closeFile (haFO__ handle_) 0{-don't bother flusing-} -- ConcHask: SAFE, won't block
314 return (handle_{ haType__ = ClosedHandle,
315 haFO__ = nullFile__ },
318 more <- unsafeInterleaveIO (lazyReadChar handle fo)
319 return (chr char : more)
324 %*********************************************************
326 \subsection{Simple output functions}
328 %*********************************************************
330 @hPutChar hdl ch@ writes the character @ch@ to the file
331 or channel managed by @hdl@. Characters may be buffered if
332 buffering is enabled for @hdl@
335 hPutChar :: Handle -> Char -> IO ()
337 wantWriteableHandle "hPutChar" handle $ \ handle_ -> do
338 let fo = haFO__ handle_
340 rc <- mayBlock fo (filePutc fo c) -- ConcHask: UNSAFE, may block.
343 else constructErrorAndFail "hPutChar"
347 @hPutStr hdl s@ writes the string @s@ to the file or
348 channel managed by @hdl@, buffering the output if needs be.
351 hPutStr :: Handle -> String -> IO ()
353 wantWriteableHandle "hPutStr" handle $ \ handle_ -> do
354 let fo = haFO__ handle_
356 case haBufferMode__ handle_ of
358 buf <- getWriteableBuf fo
361 writeLines fo buf bsz pos str
362 BlockBuffering _ -> do
363 buf <- getWriteableBuf fo
366 writeBlocks fo buf bsz pos str
371 Going across the border between Haskell and C is relatively costly,
372 so for block writes we pack the character strings on the Haskell-side
373 before passing the external write routine a pointer to the buffer.
378 #ifdef __CONCURRENT_HASKELL__
379 /* See comment in shoveString below for explanation */
380 #warning delayed update of buffer disnae work with killThread
383 #ifndef __PARALLEL_HASKELL__
384 writeLines :: ForeignObj -> Addr -> Int -> Int -> String -> IO ()
386 writeLines :: Addr -> Addr -> Int -> Int -> String -> IO ()
388 writeLines obj buf bufLen initPos s =
390 shoveString :: Int -> [Char] -> IO ()
395 At the end of a buffer write, update the buffer position
396 in the underlying file object, so that if the handle
397 is subsequently dropped by the program, the whole
398 buffer will be properly flushed.
400 There's one case where this delayed up-date of the buffer
401 position can go wrong: if a thread is killed, it might be
402 in the middle of filling up a buffer, with the result that
403 the partial buffer update is lost upon finalisation. Not
404 that killing of threads is supported at the moment.
410 primWriteCharOffAddr buf n x
411 {- Flushing on buffer exhaustion or newlines (even if it isn't the last one) -}
412 if n == bufLen || x == '\n'
414 rc <- mayBlock obj (writeFileObject obj (n + 1)) -- ConcHask: UNSAFE, may block.
416 then shoveString 0 xs
417 else constructErrorAndFail "writeLines"
419 shoveString (n + 1) xs
421 shoveString initPos s
422 #else /* ndef __HUGS__ */
423 #ifndef __PARALLEL_HASKELL__
424 writeLines :: ForeignObj -> Addr -> Int -> Int -> String -> IO ()
426 writeLines :: Addr -> Addr -> Int -> Int -> String -> IO ()
428 writeLines obj buf (I# bufLen) (I# initPos#) s =
430 write_char :: Addr -> Int# -> Char# -> IO ()
431 write_char (A# buf#) n# c# =
433 case (writeCharOffAddr# buf# n# c# s#) of s2# -> (# s2#, () #)
435 shoveString :: Int# -> [Char] -> IO ()
440 At the end of a buffer write, update the buffer position
441 in the underlying file object, so that if the handle
442 is subsequently dropped by the program, the whole
443 buffer will be properly flushed.
445 There's one case where this delayed up-date of the buffer
446 position can go wrong: if a thread is killed, it might be
447 in the middle of filling up a buffer, with the result that
448 the partial buffer update is lost upon finalisation. Not
449 that killing of threads is supported at the moment.
452 setBufWPtr obj (I# n)
456 {- Flushing on buffer exhaustion or newlines (even if it isn't the last one) -}
457 if n ==# bufLen || x `eqChar#` '\n'#
459 rc <- mayBlock obj (writeFileObject obj (I# (n +# 1#))) -- ConcHask: UNSAFE, may block.
461 then shoveString 0# xs
462 else constructErrorAndFail "writeLines"
464 shoveString (n +# 1#) xs
466 shoveString initPos# s
467 #endif /* ndef __HUGS__ */
470 #ifndef __PARALLEL_HASKELL__
471 writeBlocks :: ForeignObj -> Addr -> Int -> Int -> String -> IO ()
473 writeBlocks :: Addr -> Addr -> Int -> Int -> String -> IO ()
475 writeBlocks obj buf bufLen initPos s =
477 shoveString :: Int -> [Char] -> IO ()
482 At the end of a buffer write, update the buffer position
483 in the underlying file object, so that if the handle
484 is subsequently dropped by the program, the whole
485 buffer will be properly flushed.
487 There's one case where this delayed up-date of the buffer
488 position can go wrong: if a thread is killed, it might be
489 in the middle of filling up a buffer, with the result that
490 the partial buffer update is lost upon finalisation. However,
491 by the time killThread is supported, Haskell finalisers are also
492 likely to be in, which means the 'IOFileObject' hack can go
499 primWriteCharOffAddr buf n x
502 rc <- mayBlock obj (writeFileObject obj (n + 1)) -- ConcHask: UNSAFE, may block.
504 then shoveString 0 xs
505 else constructErrorAndFail "writeChunks"
507 shoveString (n + 1) xs
509 shoveString initPos s
510 #else /* ndef __HUGS__ */
511 #ifndef __PARALLEL_HASKELL__
512 writeBlocks :: ForeignObj -> Addr -> Int -> Int -> String -> IO ()
514 writeBlocks :: Addr -> Addr -> Int -> Int -> String -> IO ()
516 writeBlocks obj buf (I# bufLen) (I# initPos#) s =
518 write_char :: Addr -> Int# -> Char# -> IO ()
519 write_char (A# buf#) n# c# =
521 case (writeCharOffAddr# buf# n# c# s#) of s2# -> (# s2#, () #)
523 shoveString :: Int# -> [Char] -> IO ()
528 At the end of a buffer write, update the buffer position
529 in the underlying file object, so that if the handle
530 is subsequently dropped by the program, the whole
531 buffer will be properly flushed.
533 There's one case where this delayed up-date of the buffer
534 position can go wrong: if a thread is killed, it might be
535 in the middle of filling up a buffer, with the result that
536 the partial buffer update is lost upon finalisation. However,
537 by the time killThread is supported, Haskell finalisers are also
538 likely to be in, which means the 'IOFileObject' hack can go
542 setBufWPtr obj (I# n)
548 rc <- mayBlock obj (writeFileObject obj (I# (n +# 1#))) -- ConcHask: UNSAFE, may block.
550 then shoveString 0# xs
551 else constructErrorAndFail "writeChunks"
553 shoveString (n +# 1#) xs
555 shoveString initPos# s
556 #endif /* ndef __HUGS__ */
558 #ifndef __PARALLEL_HASKELL__
559 writeChars :: ForeignObj -> String -> IO ()
561 writeChars :: Addr -> String -> IO ()
563 writeChars _fo "" = return ()
564 writeChars fo (c:cs) = do
565 rc <- mayBlock fo (filePutc fo c) -- ConcHask: UNSAFE, may block.
567 then writeChars fo cs
568 else constructErrorAndFail "writeChars"
572 Computation @hPrint hdl t@ writes the string representation of {\em t}
573 given by the @shows@ function to the file or channel managed by {\em
576 [ Seem to have disappeared from the 1.4 interface - SOF 2/97 ]
579 hPrint :: Show a => Handle -> a -> IO ()
580 hPrint hdl = hPutStrLn hdl . show
583 Derived action @hPutStrLn hdl str@ writes the string \tr{str} to
584 the handle \tr{hdl}, adding a newline at the end.
587 hPutStrLn :: Handle -> String -> IO ()
588 hPutStrLn hndl str = do
595 %*********************************************************
597 \subsection{Try and bracket}
599 %*********************************************************
601 The construct @try comp@ exposes errors which occur within a
602 computation, and which are not fully handled. It always succeeds.
605 try :: IO a -> IO (Either IOError a)
606 try f = catch (do r <- f
610 bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c
611 bracket before after m = do
619 -- variant of the above where middle computation doesn't want x
620 bracket_ :: IO a -> (a -> IO b) -> IO c -> IO c
621 bracket_ before after m = do
630 %*********************************************************
632 \subsection{Standard IO}
634 %*********************************************************
636 The Prelude has from Day 1 provided a collection of common
637 IO functions. We define these here, but let the Prelude
641 putChar :: Char -> IO ()
642 putChar c = hPutChar stdout c
644 putStr :: String -> IO ()
645 putStr s = hPutStr stdout s
647 putStrLn :: String -> IO ()
648 putStrLn s = do putStr s
651 print :: Show a => a -> IO ()
652 print x = putStrLn (show x)
655 getChar = hGetChar stdin
658 getLine = hGetLine stdin
660 getContents :: IO String
661 getContents = hGetContents stdin
663 interact :: (String -> String) -> IO ()
664 interact f = do s <- getContents
667 readFile :: FilePath -> IO String
668 readFile name = openFile name ReadMode >>= hGetContents
670 writeFile :: FilePath -> String -> IO ()
671 writeFile name str = do
672 hdl <- openFile name WriteMode
676 appendFile :: FilePath -> String -> IO ()
677 appendFile name str = do
678 hdl <- openFile name AppendMode
682 readLn :: Read a => IO a
683 readLn = do l <- getLine
697 unimp s = error ("IO library: function not implemented: " ++ s)
699 type FILE_STAR = Addr
704 = Handle { name :: FilePath,
705 file :: FILE_STAR, -- C handle
706 mut :: IORef Handle_Mut, -- open/closed/semiclosed
712 = Handle_Mut { state :: HState
716 set_state :: Handle -> HState -> IO ()
717 set_state hdl new_state
718 = writeIORef (mut hdl) (Handle_Mut { state = new_state })
719 get_state :: Handle -> IO HState
721 = readIORef (mut hdl) >>= \m -> return (state m)
723 mkErr :: Handle -> String -> IO a
725 = do mut <- readIORef (mut h)
726 when (state mut /= HClosed)
727 (nh_close (file h) >> set_state h HClosed)
729 ioError (IOError msg)
734 file = primRunST nh_stdin,
735 mut = primRunST (newIORef (Handle_Mut { state = HOpen })),
742 file = primRunST nh_stdout,
743 mut = primRunST (newIORef (Handle_Mut { state = HOpen })),
750 file = primRunST nh_stderr,
751 mut = primRunST (newIORef (Handle_Mut { state = HOpen })),
756 instance Eq Handle where
757 h1 == h2 = file h1 == file h2
759 instance Show Handle where
760 showsPrec _ h = showString ("`" ++ name h ++ "'")
767 data IOMode = ReadMode | WriteMode | AppendMode | ReadWriteMode
768 deriving (Eq, Ord, Ix, Bounded, Enum, Read, Show)
770 data BufferMode = NoBuffering | LineBuffering
771 | BlockBuffering (Maybe Int)
772 deriving (Eq, Ord, Read, Show)
774 data SeekMode = AbsoluteSeek | RelativeSeek | SeekFromEnd
775 deriving (Eq, Ord, Ix, Bounded, Enum, Read, Show)
777 data HState = HOpen | HSemiClosed | HClosed
781 -- A global variable holding a list of all open handles.
782 -- Each handle is present as many times as it has been opened.
783 -- Any given file is allowed to have _either_ one writeable handle
784 -- or many readable handles in this list. The list is used to
785 -- enforce single-writer multiple reader semantics. It also
786 -- provides a list of handles for System.exitWith to flush and
787 -- close. In order not to have to put all this stuff in the
788 -- Prelude, System.exitWith merely runs prelExitWithAction,
789 -- which is originally Nothing, but which we set to Just ...
790 -- once handles appear in the list.
792 allHandles :: IORef [Handle]
793 allHandles = primRunST (newIORef [])
795 elemWriterHandles :: FilePath -> IO Bool
796 elemAllHandles :: FilePath -> IO Bool
797 addHandle :: Handle -> IO ()
798 delHandle :: Handle -> IO ()
799 cleanupHandles :: IO ()
802 = do hdls <- readIORef allHandles
803 mapM_ cleanupHandle hdls
808 >> nh_errno >>= \_ -> return ()
810 = nh_flush (file h) >> nh_close (file h)
811 >> nh_errno >>= \_ -> return ()
813 elemWriterHandles fname
814 = do hdls <- readIORef allHandles
815 let hdls_w = filter ((/= ReadMode).mode) hdls
816 return (fname `elem` (map name hdls_w))
819 = do hdls <- readIORef allHandles
820 return (fname `elem` (map name hdls))
823 = do cleanup_action <- readIORef prelCleanupAfterRunAction
824 case cleanup_action of
826 -> writeIORef prelCleanupAfterRunAction (Just cleanupHandles)
829 hdls <- readIORef allHandles
830 writeIORef allHandles (hdl : hdls)
833 = do hdls <- readIORef allHandles
834 let hdls' = takeWhile (/= hdl) hdls
835 ++ drop 1 (dropWhile (/= hdl) hdls)
836 writeIORef allHandles hdls'
840 openFile :: FilePath -> IOMode -> IO Handle
844 = (ioError.IOError) "openFile: empty file name"
847 = do not_ok <- elemWriterHandles f
849 then (ioError.IOError)
850 ("openFile: `" ++ f ++ "' in " ++ show mode
851 ++ ": is already open for writing")
852 else openFile_main f mode
855 = do not_ok <- elemAllHandles f
857 then (ioError.IOError)
858 ("openFile: `" ++ f ++ "' in " ++ show mode
859 ++ ": is already open for reading or writing")
860 else openFile_main f mode
863 = openFile_main f mode
866 = copy_String_to_cstring f >>= \nameptr ->
867 nh_open nameptr (mode2num mode) >>= \fh ->
870 then (ioError.IOError)
871 ("openFile: can't open <<" ++ f ++ ">> in " ++ show mode)
872 else do r <- newIORef (Handle_Mut { state = HOpen })
873 let hdl = Handle { name = f, file = fh,
874 mut = r, mode = mode }
878 mode2num :: IOMode -> Int
879 mode2num ReadMode = 0
880 mode2num WriteMode = 1
881 mode2num AppendMode = 2
882 mode2num ReadWriteMode
884 ("openFile <<" ++ f ++ ">>: ReadWriteMode not supported")
886 hClose :: Handle -> IO ()
888 = do mut <- readIORef (mut h)
889 putStrLn ( "hClose: state is " ++ show mut)
890 if state mut == HClosed
892 ("hClose on closed handle " ++ show h)
894 do set_state h HClosed
901 ("hClose: error closing " ++ name h)
903 hGetContents :: Handle -> IO String
906 = mkErr h ("hGetContents on non-ReadMode handle " ++ show h)
908 = do mut <- readIORef (mut h)
909 if state mut /= HOpen
911 ("hGetContents on closed/semiclosed handle " ++ show h)
913 do set_state h HSemiClosed
917 = nh_read f >>= \ci ->
920 else read_all f >>= \rest ->
921 return ((primIntToChar ci):rest)
923 hPutStr :: Handle -> String -> IO ()
926 = mkErr h ("hPutStr on ReadMode handle " ++ show h)
928 = do mut <- readIORef (mut h)
929 if state mut /= HOpen
931 ("hPutStr on closed/semiclosed handle " ++ show h)
932 else write_all (file h) s
937 = nh_write f c >> write_all f cs
939 hFileSize :: Handle -> IO Integer
941 = do sz <- nh_filesize (file h)
944 then return (fromIntegral sz)
945 else mkErr h ("hFileSize on " ++ show h)
947 hIsEOF :: Handle -> IO Bool
949 = do iseof <- nh_iseof (file h)
952 then return (iseof /= 0)
953 else mkErr h ("hIsEOF on " ++ show h)
958 hSetBuffering :: Handle -> BufferMode -> IO ()
959 hSetBuffering = unimp "IO.hSetBuffering"
960 hGetBuffering :: Handle -> IO BufferMode
961 hGetBuffering = unimp "IO.hGetBuffering"
963 hFlush :: Handle -> IO ()
965 = do mut <- readIORef (mut h)
966 if state mut /= HOpen
968 ("hFlush on closed/semiclosed file " ++ name h)
969 else nh_flush (file h)
971 hGetPosn :: Handle -> IO HandlePosn
972 hGetPosn = unimp "IO.hGetPosn"
973 hSetPosn :: HandlePosn -> IO ()
974 hSetPosn = unimp "IO.hSetPosn"
975 hSeek :: Handle -> SeekMode -> Integer -> IO ()
976 hSeek = unimp "IO.hSeek"
977 hWaitForInput :: Handle -> Int -> IO Bool
978 hWaitForInput = unimp "hWaitForInput"
979 hReady :: Handle -> IO Bool
980 hReady h = unimp "hReady" -- hWaitForInput h 0
982 hGetChar :: Handle -> IO Char
984 = nh_read (file h) >>= \ci ->
985 return (primIntToChar ci)
987 hGetLine :: Handle -> IO String
988 hGetLine h = do c <- hGetChar h
989 if c=='\n' then return ""
990 else do cs <- hGetLine h
993 hLookAhead :: Handle -> IO Char
994 hLookAhead = unimp "IO.hLookAhead"
997 hPutChar :: Handle -> Char -> IO ()
998 hPutChar h c = hPutStr h [c]
1000 hPutStrLn :: Handle -> String -> IO ()
1001 hPutStrLn h s = do { hPutStr h s; hPutChar h '\n' }
1003 hPrint :: Show a => Handle -> a -> IO ()
1004 hPrint h = hPutStrLn h . show
1006 hIsOpen, hIsClosed, hIsReadable, hIsWritable :: Handle -> IO Bool
1007 hIsOpen h = do { s <- get_state h; return (s == HOpen) }
1008 hIsClosed h = do { s <- get_state h; return (s == HClosed) }
1009 hIsReadable h = return (mode h == ReadMode)
1010 hIsWritable h = return (mode h `elem` [WriteMode, AppendMode])
1012 hIsSeekable :: Handle -> IO Bool
1013 hIsSeekable = unimp "IO.hIsSeekable"
1016 isAlreadyExistsError,
1017 isDoesNotExistError,
1018 isAlreadyInUseError,
1022 isUserError :: IOError -> Bool
1024 isIllegalOperation = unimp "IO.isIllegalOperation"
1025 isAlreadyExistsError = unimp "IO.isAlreadyExistsError"
1026 isDoesNotExistError = unimp "IO.isDoesNotExistError"
1027 isAlreadyInUseError = unimp "IO.isAlreadyInUseError"
1028 isFullError = unimp "IO.isFullError"
1029 isEOFError = unimp "IO.isEOFError"
1030 isPermissionError = unimp "IO.isPermissionError"
1031 isUserError = unimp "IO.isUserError"
1034 ioeGetErrorString :: IOError -> String
1035 ioeGetErrorString = unimp "IO.ioeGetErrorString"
1036 ioeGetHandle :: IOError -> Maybe Handle
1037 ioeGetHandle = unimp "IO.ioeGetHandle"
1038 ioeGetFileName :: IOError -> Maybe FilePath
1039 ioeGetFileName = unimp "IO.ioeGetFileName"
1041 try :: IO a -> IO (Either IOError a)
1042 try p = catch (p >>= (return . Right)) (return . Left)
1044 bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c
1045 bracket before after m = do
1053 -- variant of the above where middle computation doesn't want x
1054 bracket_ :: IO a -> (a -> IO b) -> IO c -> IO c
1055 bracket_ before after m = do
1063 -- TODO: Hugs/slurpFile
1064 slurpFile = unimp "IO.slurpFile"
1067 #endif /* #ifndef __HUGS__ */