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
90 import PrimPrel ( IORef
92 , prelCleanupAfterRunAction
93 , copy_String_to_cstring
95 , primWriteCharOffAddr
118 import PrelHandle -- much of the real stuff is in here
120 import PrelRead ( readParen, Read(..), reads, lex,
124 import PrelMaybe ( Either(..), Maybe(..) )
125 import PrelAddr ( Addr(..), nullAddr )
126 import PrelByteArr ( ByteArray )
127 import PrelPack ( unpackNBytesAccST )
128 import PrelException ( ioError, catch )
131 #ifndef __PARALLEL_HASKELL__
132 import PrelForeign ( ForeignObj )
135 import Char ( ord, chr )
137 #endif /* ndef __HUGS__ */
141 %*********************************************************
143 \subsection{Simple input operations}
145 %*********************************************************
147 Computation @hReady hdl@ indicates whether at least
148 one item is available for input from handle {\em hdl}.
150 @hWaitForInput@ is the generalisation, wait for \tr{n} milliseconds
151 before deciding whether the Handle has run dry or not.
153 If @hWaitForInput@ finds anything in the Handle's buffer, it immediately returns.
154 If not, it tries to read from the underlying OS handle. Notice that
155 for buffered Handles connected to terminals this means waiting until a complete
159 hReady :: Handle -> IO Bool
160 hReady h = hWaitForInput h 0
162 hWaitForInput :: Handle -> Int -> IO Bool
163 hWaitForInput handle msecs =
164 wantReadableHandle "hWaitForInput" handle $ \ handle_ -> do
165 rc <- inputReady (haFO__ handle_) (msecs::Int) -- ConcHask: SAFE, won't block
169 _ -> constructErrorAndFail "hWaitForInput"
172 @hGetChar hdl@ reads the next character from handle @hdl@,
173 blocking until a character is available.
176 hGetChar :: Handle -> IO Char
178 c <- mayBlockRead "hGetChar" handle fileGetc
182 If EOF is reached before EOL is encountered, ignore the
183 EOF and return the partial line. Next attempt at calling
184 hGetLine on the handle will yield an EOF IO exception though.
186 hGetLine :: Handle -> IO String
200 if isEOFError err then
212 @hLookahead hdl@ returns the next character from handle @hdl@
213 without removing it from the input buffer, blocking until a
214 character is available.
217 hLookAhead :: Handle -> IO Char
218 hLookAhead handle = do
219 rc <- mayBlockRead "hLookAhead" handle fileLookAhead
224 %*********************************************************
226 \subsection{Getting the entire contents of a handle}
228 %*********************************************************
230 @hGetContents hdl@ returns the list of characters corresponding
231 to the unread portion of the channel or file managed by @hdl@,
232 which is made semi-closed.
235 hGetContents :: Handle -> IO String
236 hGetContents handle =
237 -- can't use wantReadableHandle here, because we want to side effect
239 withHandle handle $ \ handle_ -> do
240 case haType__ handle_ of
241 ErrorHandle theError -> ioError theError
242 ClosedHandle -> ioe_closedHandle "hGetContents" handle
243 SemiClosedHandle -> ioe_closedHandle "hGetContents" handle
244 AppendHandle -> ioError not_readable_error
245 WriteHandle -> ioError not_readable_error
248 To avoid introducing an extra layer of buffering here,
249 we provide three lazy read methods, based on character,
250 line, and block buffering.
252 let handle_' = handle_{ haType__ = SemiClosedHandle }
253 case (haBufferMode__ handle_) of
255 str <- unsafeInterleaveIO (lazyReadLine handle (haFO__ handle_))
256 return (handle_', str)
257 BlockBuffering _ -> do
258 str <- unsafeInterleaveIO (lazyReadBlock handle (haFO__ handle_))
259 return (handle_', str)
261 str <- unsafeInterleaveIO (lazyReadChar handle (haFO__ handle_))
262 return (handle_', str)
265 IOError (Just handle) IllegalOperation "hGetContents"
266 ("handle is not open for reading")
269 Note that someone may close the semi-closed handle (or change its buffering),
270 so each these lazy read functions are pulled on, they have to check whether
271 the handle has indeed been closed.
274 #ifndef __PARALLEL_HASKELL__
275 lazyReadBlock :: Handle -> ForeignObj -> IO String
276 lazyReadLine :: Handle -> ForeignObj -> IO String
277 lazyReadChar :: Handle -> ForeignObj -> IO String
279 lazyReadBlock :: Handle -> Addr -> IO String
280 lazyReadLine :: Handle -> Addr -> IO String
281 lazyReadChar :: Handle -> Addr -> IO String
284 lazyReadBlock handle fo = do
285 buf <- getBufStart fo 0
286 bytes <- mayBlock fo (readBlock fo) -- ConcHask: UNSAFE, may block.
288 -3 -> -- buffering has been turned off, use lazyReadChar instead
289 lazyReadChar handle fo
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 (lazyReadBlock handle fo)
299 stToIO (unpackNBytesAccST buf bytes more)
301 lazyReadLine handle fo = do
302 bytes <- mayBlock fo (readLine fo) -- ConcHask: UNSAFE, may block.
304 -3 -> -- buffering has been turned off, use lazyReadChar instead
305 lazyReadChar handle fo
306 -2 -> return "" -- handle closed by someone else, stop reading.
307 -1 -> -- an error occurred, close the handle
308 withHandle handle $ \ handle_ -> do
309 closeFile (haFO__ handle_) 0{- don't bother flushing-} -- ConcHask: SAFE, won't block
310 return (handle_ { haType__ = ClosedHandle,
311 haFO__ = nullFile__ },
314 more <- unsafeInterleaveIO (lazyReadLine handle fo)
315 buf <- getBufStart fo bytes -- ConcHask: won't block
316 stToIO (unpackNBytesAccST buf bytes more)
318 lazyReadChar handle fo = do
319 char <- mayBlock fo (readChar fo) -- ConcHask: UNSAFE, may block.
321 -4 -> -- buffering is now block-buffered, use lazyReadBlock instead
322 lazyReadBlock handle fo
324 -3 -> -- buffering is now line-buffered, use lazyReadLine instead
325 lazyReadLine handle fo
327 -1 -> -- error, silently close handle.
328 withHandle handle $ \ handle_ -> do
329 closeFile (haFO__ handle_) 0{-don't bother flusing-} -- ConcHask: SAFE, won't block
330 return (handle_{ haType__ = ClosedHandle,
331 haFO__ = nullFile__ },
334 more <- unsafeInterleaveIO (lazyReadChar handle fo)
335 return (chr char : more)
340 %*********************************************************
342 \subsection{Simple output functions}
344 %*********************************************************
346 @hPutChar hdl ch@ writes the character @ch@ to the file
347 or channel managed by @hdl@. Characters may be buffered if
348 buffering is enabled for @hdl@
351 hPutChar :: Handle -> Char -> IO ()
353 wantWriteableHandle "hPutChar" handle $ \ handle_ -> do
354 let fo = haFO__ handle_
356 rc <- mayBlock fo (filePutc fo c) -- ConcHask: UNSAFE, may block.
359 else constructErrorAndFail "hPutChar"
363 @hPutStr hdl s@ writes the string @s@ to the file or
364 channel managed by @hdl@, buffering the output if needs be.
367 hPutStr :: Handle -> String -> IO ()
369 wantWriteableHandle "hPutStr" handle $ \ handle_ -> do
370 let fo = haFO__ handle_
372 case haBufferMode__ handle_ of
374 buf <- getWriteableBuf fo
377 writeLines fo buf bsz pos str
378 BlockBuffering _ -> do
379 buf <- getWriteableBuf fo
382 writeBlocks fo buf bsz pos str
387 Going across the border between Haskell and C is relatively costly,
388 so for block writes we pack the character strings on the Haskell-side
389 before passing the external write routine a pointer to the buffer.
394 #ifdef __CONCURRENT_HASKELL__
395 /* See comment in shoveString below for explanation */
396 #warning delayed update of buffer disnae work with killThread
399 #ifndef __PARALLEL_HASKELL__
400 writeLines :: ForeignObj -> Addr -> Int -> Int -> String -> IO ()
402 writeLines :: Addr -> Addr -> Int -> Int -> String -> IO ()
404 writeLines obj buf bufLen initPos s =
406 shoveString :: Int -> [Char] -> IO ()
411 At the end of a buffer write, update the buffer position
412 in the underlying file object, so that if the handle
413 is subsequently dropped by the program, the whole
414 buffer will be properly flushed.
416 There's one case where this delayed up-date of the buffer
417 position can go wrong: if a thread is killed, it might be
418 in the middle of filling up a buffer, with the result that
419 the partial buffer update is lost upon finalisation. Not
420 that killing of threads is supported at the moment.
426 primWriteCharOffAddr buf n x
427 {- Flushing on buffer exhaustion or newlines (even if it isn't the last one) -}
428 if n == bufLen || x == '\n'
430 rc <- mayBlock obj (writeFileObject obj (n + 1)) -- ConcHask: UNSAFE, may block.
432 then shoveString 0 xs
433 else constructErrorAndFail "writeLines"
435 shoveString (n + 1) xs
437 shoveString initPos s
438 #else /* ndef __HUGS__ */
439 #ifndef __PARALLEL_HASKELL__
440 writeLines :: ForeignObj -> Addr -> Int -> Int -> String -> IO ()
442 writeLines :: Addr -> Addr -> Int -> Int -> String -> IO ()
444 writeLines obj buf (I# bufLen) (I# initPos#) s =
446 write_char :: Addr -> Int# -> Char# -> IO ()
447 write_char (A# buf#) n# c# =
449 case (writeCharOffAddr# buf# n# c# s#) of s2# -> (# s2#, () #)
451 shoveString :: Int# -> [Char] -> IO ()
456 At the end of a buffer write, update the buffer position
457 in the underlying file object, so that if the handle
458 is subsequently dropped by the program, the whole
459 buffer will be properly flushed.
461 There's one case where this delayed up-date of the buffer
462 position can go wrong: if a thread is killed, it might be
463 in the middle of filling up a buffer, with the result that
464 the partial buffer update is lost upon finalisation. Not
465 that killing of threads is supported at the moment.
468 setBufWPtr obj (I# n)
472 {- Flushing on buffer exhaustion or newlines (even if it isn't the last one) -}
473 if n ==# bufLen || x `eqChar#` '\n'#
475 rc <- mayBlock obj (writeFileObject obj (I# (n +# 1#))) -- ConcHask: UNSAFE, may block.
477 then shoveString 0# xs
478 else constructErrorAndFail "writeLines"
480 shoveString (n +# 1#) xs
482 shoveString initPos# s
483 #endif /* ndef __HUGS__ */
486 #ifndef __PARALLEL_HASKELL__
487 writeBlocks :: ForeignObj -> Addr -> Int -> Int -> String -> IO ()
489 writeBlocks :: Addr -> Addr -> Int -> Int -> String -> IO ()
491 writeBlocks obj buf bufLen initPos s =
493 shoveString :: Int -> [Char] -> IO ()
498 At the end of a buffer write, update the buffer position
499 in the underlying file object, so that if the handle
500 is subsequently dropped by the program, the whole
501 buffer will be properly flushed.
503 There's one case where this delayed up-date of the buffer
504 position can go wrong: if a thread is killed, it might be
505 in the middle of filling up a buffer, with the result that
506 the partial buffer update is lost upon finalisation. However,
507 by the time killThread is supported, Haskell finalisers are also
508 likely to be in, which means the 'IOFileObject' hack can go
515 primWriteCharOffAddr buf n x
518 rc <- mayBlock obj (writeFileObject obj (n + 1)) -- ConcHask: UNSAFE, may block.
520 then shoveString 0 xs
521 else constructErrorAndFail "writeChunks"
523 shoveString (n + 1) xs
525 shoveString initPos s
526 #else /* ndef __HUGS__ */
527 #ifndef __PARALLEL_HASKELL__
528 writeBlocks :: ForeignObj -> Addr -> Int -> Int -> String -> IO ()
530 writeBlocks :: Addr -> Addr -> Int -> Int -> String -> IO ()
532 writeBlocks obj buf (I# bufLen) (I# initPos#) s =
534 write_char :: Addr -> Int# -> Char# -> IO ()
535 write_char (A# buf#) n# c# =
537 case (writeCharOffAddr# buf# n# c# s#) of s2# -> (# s2#, () #)
539 shoveString :: Int# -> [Char] -> IO ()
544 At the end of a buffer write, update the buffer position
545 in the underlying file object, so that if the handle
546 is subsequently dropped by the program, the whole
547 buffer will be properly flushed.
549 There's one case where this delayed up-date of the buffer
550 position can go wrong: if a thread is killed, it might be
551 in the middle of filling up a buffer, with the result that
552 the partial buffer update is lost upon finalisation. However,
553 by the time killThread is supported, Haskell finalisers are also
554 likely to be in, which means the 'IOFileObject' hack can go
558 setBufWPtr obj (I# n)
564 rc <- mayBlock obj (writeFileObject obj (I# (n +# 1#))) -- ConcHask: UNSAFE, may block.
566 then shoveString 0# xs
567 else constructErrorAndFail "writeChunks"
569 shoveString (n +# 1#) xs
571 shoveString initPos# s
572 #endif /* ndef __HUGS__ */
574 #ifndef __PARALLEL_HASKELL__
575 writeChars :: ForeignObj -> String -> IO ()
577 writeChars :: Addr -> String -> IO ()
579 writeChars _fo "" = return ()
580 writeChars fo (c:cs) = do
581 rc <- mayBlock fo (filePutc fo c) -- ConcHask: UNSAFE, may block.
583 then writeChars fo cs
584 else constructErrorAndFail "writeChars"
588 Computation @hPrint hdl t@ writes the string representation of {\em t}
589 given by the @shows@ function to the file or channel managed by {\em
592 [ Seem to have disappeared from the 1.4 interface - SOF 2/97 ]
595 hPrint :: Show a => Handle -> a -> IO ()
596 hPrint hdl = hPutStrLn hdl . show
599 Derived action @hPutStrLn hdl str@ writes the string \tr{str} to
600 the handle \tr{hdl}, adding a newline at the end.
603 hPutStrLn :: Handle -> String -> IO ()
604 hPutStrLn hndl str = do
611 %*********************************************************
613 \subsection{Try and bracket}
615 %*********************************************************
617 The construct @try comp@ exposes errors which occur within a
618 computation, and which are not fully handled. It always succeeds.
621 try :: IO a -> IO (Either IOError a)
622 try f = catch (do r <- f
626 bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c
627 bracket before after m = do
635 -- variant of the above where middle computation doesn't want x
636 bracket_ :: IO a -> (a -> IO b) -> IO c -> IO c
637 bracket_ before after m = do
646 %*********************************************************
648 \subsection{Standard IO}
650 %*********************************************************
652 The Prelude has from Day 1 provided a collection of common
653 IO functions. We define these here, but let the Prelude
657 putChar :: Char -> IO ()
658 putChar c = hPutChar stdout c
660 putStr :: String -> IO ()
661 putStr s = hPutStr stdout s
663 putStrLn :: String -> IO ()
664 putStrLn s = do putStr s
667 print :: Show a => a -> IO ()
668 print x = putStrLn (show x)
671 getChar = hGetChar stdin
674 getLine = hGetLine stdin
676 getContents :: IO String
677 getContents = hGetContents stdin
679 interact :: (String -> String) -> IO ()
680 interact f = do s <- getContents
683 readFile :: FilePath -> IO String
684 readFile name = openFile name ReadMode >>= hGetContents
686 writeFile :: FilePath -> String -> IO ()
687 writeFile name str = do
688 hdl <- openFile name WriteMode
692 appendFile :: FilePath -> String -> IO ()
693 appendFile name str = do
694 hdl <- openFile name AppendMode
698 readLn :: Read a => IO a
699 readLn = do l <- getLine
713 unimp s = error ("IO library: function not implemented: " ++ s)
715 type FILE_STAR = Addr
720 = Handle { name :: FilePath,
721 file :: FILE_STAR, -- C handle
722 mut :: IORef Handle_Mut, -- open/closed/semiclosed
728 = Handle_Mut { state :: HState
732 set_state :: Handle -> HState -> IO ()
733 set_state hdl new_state
734 = writeIORef (mut hdl) (Handle_Mut { state = new_state })
735 get_state :: Handle -> IO HState
737 = readIORef (mut hdl) >>= \m -> return (state m)
739 mkErr :: Handle -> String -> IO a
741 = do mut <- readIORef (mut h)
742 when (state mut /= HClosed)
743 (nh_close (file h) >> set_state h HClosed)
745 ioError (IOError msg)
750 file = unsafePerformIO nh_stdin,
751 mut = unsafePerformIO (newIORef (Handle_Mut { state = HOpen })),
758 file = unsafePerformIO nh_stdout,
759 mut = unsafePerformIO (newIORef (Handle_Mut { state = HOpen })),
766 file = unsafePerformIO nh_stderr,
767 mut = unsafePerformIO (newIORef (Handle_Mut { state = HOpen })),
772 instance Eq Handle where
773 h1 == h2 = file h1 == file h2
775 instance Show Handle where
776 showsPrec _ h = showString ("`" ++ name h ++ "'")
783 data IOMode = ReadMode | WriteMode | AppendMode | ReadWriteMode
784 deriving (Eq, Ord, Ix, Bounded, Enum, Read, Show)
786 data BufferMode = NoBuffering | LineBuffering
787 | BlockBuffering (Maybe Int)
788 deriving (Eq, Ord, Read, Show)
790 data SeekMode = AbsoluteSeek | RelativeSeek | SeekFromEnd
791 deriving (Eq, Ord, Ix, Bounded, Enum, Read, Show)
793 data HState = HOpen | HSemiClosed | HClosed
797 -- A global variable holding a list of all open handles.
798 -- Each handle is present as many times as it has been opened.
799 -- Any given file is allowed to have _either_ one writeable handle
800 -- or many readable handles in this list. The list is used to
801 -- enforce single-writer multiple reader semantics. It also
802 -- provides a list of handles for System.exitWith to flush and
803 -- close. In order not to have to put all this stuff in the
804 -- Prelude, System.exitWith merely runs prelExitWithAction,
805 -- which is originally Nothing, but which we set to Just ...
806 -- once handles appear in the list.
808 allHandles :: IORef [Handle]
809 allHandles = unsafePerformIO (newIORef [])
811 elemWriterHandles :: FilePath -> IO Bool
812 elemAllHandles :: FilePath -> IO Bool
813 addHandle :: Handle -> IO ()
814 delHandle :: Handle -> IO ()
815 cleanupHandles :: IO ()
818 = do hdls <- readIORef allHandles
819 mapM_ cleanupHandle hdls
824 >> nh_errno >>= \_ -> return ()
826 = nh_flush (file h) >> nh_close (file h)
827 >> nh_errno >>= \_ -> return ()
829 elemWriterHandles fname
830 = do hdls <- readIORef allHandles
831 let hdls_w = filter ((/= ReadMode).mode) hdls
832 return (fname `elem` (map name hdls_w))
835 = do hdls <- readIORef allHandles
836 return (fname `elem` (map name hdls))
839 = do cleanup_action <- readIORef prelCleanupAfterRunAction
840 case cleanup_action of
842 -> writeIORef prelCleanupAfterRunAction (Just cleanupHandles)
845 hdls <- readIORef allHandles
846 writeIORef allHandles (hdl : hdls)
849 = do hdls <- readIORef allHandles
850 let hdls' = takeWhile (/= hdl) hdls
851 ++ drop 1 (dropWhile (/= hdl) hdls)
852 writeIORef allHandles hdls'
856 openFile :: FilePath -> IOMode -> IO Handle
860 = (ioError.IOError) "openFile: empty file name"
863 = do not_ok <- elemWriterHandles f
865 then (ioError.IOError)
866 ("openFile: `" ++ f ++ "' in " ++ show mode
867 ++ ": is already open for writing")
868 else openFile_main f mode
871 = do not_ok <- elemAllHandles f
873 then (ioError.IOError)
874 ("openFile: `" ++ f ++ "' in " ++ show mode
875 ++ ": is already open for reading or writing")
876 else openFile_main f mode
879 = openFile_main f mode
882 = copy_String_to_cstring f >>= \nameptr ->
883 nh_open nameptr (mode2num mode) >>= \fh ->
886 then (ioError.IOError)
887 ("openFile: can't open <<" ++ f ++ ">> in " ++ show mode)
888 else do r <- newIORef (Handle_Mut { state = HOpen })
889 let hdl = Handle { name = f, file = fh,
890 mut = r, mode = mode }
894 mode2num :: IOMode -> Int
895 mode2num ReadMode = 0
896 mode2num WriteMode = 1
897 mode2num AppendMode = 2
898 mode2num ReadWriteMode
900 ("openFile <<" ++ f ++ ">>: ReadWriteMode not supported")
902 hClose :: Handle -> IO ()
904 = do mut <- readIORef (mut h)
905 if state mut == HClosed
907 ("hClose on closed handle " ++ show h)
909 do set_state h HClosed
916 ("hClose: error closing " ++ name h)
918 hGetContents :: Handle -> IO String
921 = mkErr h ("hGetContents on non-ReadMode handle " ++ show h)
923 = do mut <- readIORef (mut h)
924 if state mut /= HOpen
926 ("hGetContents on closed/semiclosed handle " ++ show h)
928 do set_state h HSemiClosed
932 = nh_read f >>= \ci ->
935 else read_all f >>= \rest ->
936 return ((primIntToChar ci):rest)
938 hPutStr :: Handle -> String -> IO ()
941 = mkErr h ("hPutStr on ReadMode handle " ++ show h)
943 = do mut <- readIORef (mut h)
944 if state mut /= HOpen
946 ("hPutStr on closed/semiclosed handle " ++ show h)
947 else write_all (file h) s
952 = nh_write f c >> write_all f cs
954 hFileSize :: Handle -> IO Integer
956 = do sz <- nh_filesize (file h)
959 then return (fromIntegral sz)
960 else mkErr h ("hFileSize on " ++ show h)
962 hIsEOF :: Handle -> IO Bool
964 = do iseof <- nh_iseof (file h)
967 then return (iseof /= 0)
968 else mkErr h ("hIsEOF on " ++ show h)
973 hSetBuffering :: Handle -> BufferMode -> IO ()
974 hSetBuffering = unimp "IO.hSetBuffering"
975 hGetBuffering :: Handle -> IO BufferMode
976 hGetBuffering = unimp "IO.hGetBuffering"
978 hFlush :: Handle -> IO ()
980 = do mut <- readIORef (mut h)
981 if state mut /= HOpen
983 ("hFlush on closed/semiclosed file " ++ name h)
984 else nh_flush (file h)
986 hGetPosn :: Handle -> IO HandlePosn
987 hGetPosn = unimp "IO.hGetPosn"
988 hSetPosn :: HandlePosn -> IO ()
989 hSetPosn = unimp "IO.hSetPosn"
990 hSeek :: Handle -> SeekMode -> Integer -> IO ()
991 hSeek = unimp "IO.hSeek"
992 hWaitForInput :: Handle -> Int -> IO Bool
993 hWaitForInput = unimp "hWaitForInput"
994 hReady :: Handle -> IO Bool
995 hReady h = unimp "hReady" -- hWaitForInput h 0
997 hGetChar :: Handle -> IO Char
999 = nh_read (file h) >>= \ci ->
1000 return (primIntToChar ci)
1002 hGetLine :: Handle -> IO String
1003 hGetLine h = do c <- hGetChar h
1004 if c=='\n' then return ""
1005 else do cs <- hGetLine h
1008 hLookAhead :: Handle -> IO Char
1009 hLookAhead = unimp "IO.hLookAhead"
1012 hPutChar :: Handle -> Char -> IO ()
1013 hPutChar h c = hPutStr h [c]
1015 hPutStrLn :: Handle -> String -> IO ()
1016 hPutStrLn h s = do { hPutStr h s; hPutChar h '\n' }
1018 hPrint :: Show a => Handle -> a -> IO ()
1019 hPrint h = hPutStrLn h . show
1021 hIsOpen, hIsClosed, hIsReadable, hIsWritable :: Handle -> IO Bool
1022 hIsOpen h = do { s <- get_state h; return (s == HOpen) }
1023 hIsClosed h = do { s <- get_state h; return (s == HClosed) }
1024 hIsReadable h = return (mode h == ReadMode)
1025 hIsWritable h = return (mode h `elem` [WriteMode, AppendMode])
1027 hIsSeekable :: Handle -> IO Bool
1028 hIsSeekable = unimp "IO.hIsSeekable"
1031 isAlreadyExistsError,
1032 isDoesNotExistError,
1033 isAlreadyInUseError,
1037 isUserError :: IOError -> Bool
1039 isIllegalOperation = unimp "IO.isIllegalOperation"
1040 isAlreadyExistsError = unimp "IO.isAlreadyExistsError"
1041 isDoesNotExistError = unimp "IO.isDoesNotExistError"
1042 isAlreadyInUseError = unimp "IO.isAlreadyInUseError"
1043 isFullError = unimp "IO.isFullError"
1044 isEOFError = unimp "IO.isEOFError"
1045 isPermissionError = unimp "IO.isPermissionError"
1046 isUserError = unimp "IO.isUserError"
1049 ioeGetErrorString :: IOError -> String
1050 ioeGetErrorString = unimp "IO.ioeGetErrorString"
1051 ioeGetHandle :: IOError -> Maybe Handle
1052 ioeGetHandle = unimp "IO.ioeGetHandle"
1053 ioeGetFileName :: IOError -> Maybe FilePath
1054 ioeGetFileName = unimp "IO.ioeGetFileName"
1056 try :: IO a -> IO (Either IOError a)
1057 try p = catch (p >>= (return . Right)) (return . Left)
1059 bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c
1060 bracket before after m = do
1068 -- variant of the above where middle computation doesn't want x
1069 bracket_ :: IO a -> (a -> IO b) -> IO c -> IO c
1070 bracket_ before after m = do
1078 -- TODO: Hugs/slurpFile
1079 slurpFile = unimp "IO.slurpFile"
1082 #endif /* #ifndef __HUGS__ */