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
97 import privileged Prelude ( IORef
99 , prelCleanupAfterRunAction
100 , copy_String_to_cstring
102 , primWriteCharOffAddr
127 import PrelHandle -- much of the real stuff is in here
129 import PrelRead ( readParen, Read(..), reads, lex,
133 import PrelMaybe ( Either(..), Maybe(..) )
134 import PrelAddr ( Addr(..), nullAddr )
135 import PrelByteArr ( ByteArray )
136 import PrelPack ( unpackNBytesAccST )
137 import PrelException ( ioError, catch )
140 #ifndef __PARALLEL_HASKELL__
141 import PrelForeign ( ForeignObj )
144 import Char ( ord, chr )
146 #endif /* ndef __HUGS__ */
150 %*********************************************************
152 \subsection{Simple input operations}
154 %*********************************************************
156 Computation @hReady hdl@ indicates whether at least
157 one item is available for input from handle {\em hdl}.
159 @hWaitForInput@ is the generalisation, wait for \tr{n} milliseconds
160 before deciding whether the Handle has run dry or not.
162 If @hWaitForInput@ finds anything in the Handle's buffer, it immediately returns.
163 If not, it tries to read from the underlying OS handle. Notice that
164 for buffered Handles connected to terminals this means waiting until a complete
168 hReady :: Handle -> IO Bool
169 hReady h = hWaitForInput h 0
171 hWaitForInput :: Handle -> Int -> IO Bool
172 hWaitForInput handle msecs =
173 wantReadableHandle "hWaitForInput" handle $ \ handle_ -> do
174 rc <- inputReady (haFO__ handle_) (msecs::Int) -- ConcHask: SAFE, won't block
178 _ -> constructErrorAndFail "hWaitForInput"
181 @hGetChar hdl@ reads the next character from handle @hdl@,
182 blocking until a character is available.
185 hGetChar :: Handle -> IO Char
187 c <- mayBlockRead "hGetChar" handle fileGetc
191 If EOF is reached before EOL is encountered, ignore the
192 EOF and return the partial line. Next attempt at calling
193 hGetLine on the handle will yield an EOF IO exception though.
195 hGetLine :: Handle -> IO String
209 if isEOFError err then
221 @hLookahead hdl@ returns the next character from handle @hdl@
222 without removing it from the input buffer, blocking until a
223 character is available.
226 hLookAhead :: Handle -> IO Char
227 hLookAhead handle = do
228 rc <- mayBlockRead "hLookAhead" handle fileLookAhead
233 %*********************************************************
235 \subsection{Getting the entire contents of a handle}
237 %*********************************************************
239 @hGetContents hdl@ returns the list of characters corresponding
240 to the unread portion of the channel or file managed by @hdl@,
241 which is made semi-closed.
244 hGetContents :: Handle -> IO String
245 hGetContents handle =
246 -- can't use wantReadableHandle here, because we want to side effect
248 withHandle handle $ \ handle_ -> do
249 case haType__ handle_ of
250 ErrorHandle theError -> ioError theError
251 ClosedHandle -> ioe_closedHandle "hGetContents" handle
252 SemiClosedHandle -> ioe_closedHandle "hGetContents" handle
253 AppendHandle -> ioError not_readable_error
254 WriteHandle -> ioError not_readable_error
257 To avoid introducing an extra layer of buffering here,
258 we provide three lazy read methods, based on character,
259 line, and block buffering.
261 let handle_' = handle_{ haType__ = SemiClosedHandle }
262 case (haBufferMode__ handle_) of
264 str <- unsafeInterleaveIO (lazyReadLine handle (haFO__ handle_))
265 return (handle_', str)
266 BlockBuffering _ -> do
267 str <- unsafeInterleaveIO (lazyReadBlock handle (haFO__ handle_))
268 return (handle_', str)
270 str <- unsafeInterleaveIO (lazyReadChar handle (haFO__ handle_))
271 return (handle_', str)
274 IOError (Just handle) IllegalOperation "hGetContents"
275 ("handle is not open for reading")
278 Note that someone may close the semi-closed handle (or change its buffering),
279 so each these lazy read functions are pulled on, they have to check whether
280 the handle has indeed been closed.
283 #ifndef __PARALLEL_HASKELL__
284 lazyReadBlock :: Handle -> ForeignObj -> IO String
285 lazyReadLine :: Handle -> ForeignObj -> IO String
286 lazyReadChar :: Handle -> ForeignObj -> IO String
288 lazyReadBlock :: Handle -> Addr -> IO String
289 lazyReadLine :: Handle -> Addr -> IO String
290 lazyReadChar :: Handle -> Addr -> IO String
293 lazyReadBlock handle fo = do
294 buf <- getBufStart fo 0
295 bytes <- mayBlock fo (readBlock fo) -- ConcHask: UNSAFE, may block.
297 -3 -> -- buffering has been turned off, use lazyReadChar instead
298 lazyReadChar handle fo
300 -1 -> -- an error occurred, close the handle
301 withHandle handle $ \ handle_ -> do
302 closeFile (haFO__ handle_) 0{-don't bother flushing-} -- ConcHask: SAFE, won't block.
303 return (handle_ { haType__ = ClosedHandle,
304 haFO__ = nullFile__ },
307 more <- unsafeInterleaveIO (lazyReadBlock handle fo)
308 stToIO (unpackNBytesAccST buf bytes more)
310 lazyReadLine handle fo = do
311 bytes <- mayBlock fo (readLine fo) -- ConcHask: UNSAFE, may block.
313 -3 -> -- buffering has been turned off, use lazyReadChar instead
314 lazyReadChar handle fo
315 -2 -> return "" -- handle closed by someone else, stop reading.
316 -1 -> -- an error occurred, close the handle
317 withHandle handle $ \ handle_ -> do
318 closeFile (haFO__ handle_) 0{- don't bother flushing-} -- ConcHask: SAFE, won't block
319 return (handle_ { haType__ = ClosedHandle,
320 haFO__ = nullFile__ },
323 more <- unsafeInterleaveIO (lazyReadLine handle fo)
324 buf <- getBufStart fo bytes -- ConcHask: won't block
325 stToIO (unpackNBytesAccST buf bytes more)
327 lazyReadChar handle fo = do
328 char <- mayBlock fo (readChar fo) -- ConcHask: UNSAFE, may block.
330 -4 -> -- buffering is now block-buffered, use lazyReadBlock instead
331 lazyReadBlock handle fo
333 -3 -> -- buffering is now line-buffered, use lazyReadLine instead
334 lazyReadLine handle fo
336 -1 -> -- error, silently close handle.
337 withHandle handle $ \ handle_ -> do
338 closeFile (haFO__ handle_) 0{-don't bother flusing-} -- ConcHask: SAFE, won't block
339 return (handle_{ haType__ = ClosedHandle,
340 haFO__ = nullFile__ },
343 more <- unsafeInterleaveIO (lazyReadChar handle fo)
344 return (chr char : more)
349 %*********************************************************
351 \subsection{Simple output functions}
353 %*********************************************************
355 @hPutChar hdl ch@ writes the character @ch@ to the file
356 or channel managed by @hdl@. Characters may be buffered if
357 buffering is enabled for @hdl@
360 hPutChar :: Handle -> Char -> IO ()
362 wantWriteableHandle "hPutChar" handle $ \ handle_ -> do
363 let fo = haFO__ handle_
365 rc <- mayBlock fo (filePutc fo c) -- ConcHask: UNSAFE, may block.
368 else constructErrorAndFail "hPutChar"
372 @hPutStr hdl s@ writes the string @s@ to the file or
373 channel managed by @hdl@, buffering the output if needs be.
376 hPutStr :: Handle -> String -> IO ()
378 wantWriteableHandle "hPutStr" handle $ \ handle_ -> do
379 let fo = haFO__ handle_
381 case haBufferMode__ handle_ of
383 buf <- getWriteableBuf fo
386 writeLines fo buf bsz pos str
387 BlockBuffering _ -> do
388 buf <- getWriteableBuf fo
391 writeBlocks fo buf bsz pos str
396 Going across the border between Haskell and C is relatively costly,
397 so for block writes we pack the character strings on the Haskell-side
398 before passing the external write routine a pointer to the buffer.
403 #ifdef __CONCURRENT_HASKELL__
404 /* See comment in shoveString below for explanation */
405 #warning delayed update of buffer disnae work with killThread
408 #ifndef __PARALLEL_HASKELL__
409 writeLines :: ForeignObj -> Addr -> Int -> Int -> String -> IO ()
411 writeLines :: Addr -> Addr -> Int -> Int -> String -> IO ()
413 writeLines obj buf bufLen initPos s =
415 shoveString :: Int -> [Char] -> IO ()
420 At the end of a buffer write, update the buffer position
421 in the underlying file object, so that if the handle
422 is subsequently dropped by the program, the whole
423 buffer will be properly flushed.
425 There's one case where this delayed up-date of the buffer
426 position can go wrong: if a thread is killed, it might be
427 in the middle of filling up a buffer, with the result that
428 the partial buffer update is lost upon finalisation. Not
429 that killing of threads is supported at the moment.
435 primWriteCharOffAddr buf n x
436 {- Flushing on buffer exhaustion or newlines (even if it isn't the last one) -}
437 if n == bufLen || x == '\n'
439 rc <- mayBlock obj (writeFileObject obj (n + 1)) -- ConcHask: UNSAFE, may block.
441 then shoveString 0 xs
442 else constructErrorAndFail "writeLines"
444 shoveString (n + 1) xs
446 shoveString initPos s
447 #else /* ndef __HUGS__ */
448 #ifndef __PARALLEL_HASKELL__
449 writeLines :: ForeignObj -> Addr -> Int -> Int -> String -> IO ()
451 writeLines :: Addr -> Addr -> Int -> Int -> String -> IO ()
453 writeLines obj buf (I# bufLen) (I# initPos#) s =
455 write_char :: Addr -> Int# -> Char# -> IO ()
456 write_char (A# buf#) n# c# =
458 case (writeCharOffAddr# buf# n# c# s#) of s2# -> (# s2#, () #)
460 shoveString :: Int# -> [Char] -> IO ()
465 At the end of a buffer write, update the buffer position
466 in the underlying file object, so that if the handle
467 is subsequently dropped by the program, the whole
468 buffer will be properly flushed.
470 There's one case where this delayed up-date of the buffer
471 position can go wrong: if a thread is killed, it might be
472 in the middle of filling up a buffer, with the result that
473 the partial buffer update is lost upon finalisation. Not
474 that killing of threads is supported at the moment.
477 setBufWPtr obj (I# n)
481 {- Flushing on buffer exhaustion or newlines (even if it isn't the last one) -}
482 if n ==# bufLen || x `eqChar#` '\n'#
484 rc <- mayBlock obj (writeFileObject obj (I# (n +# 1#))) -- ConcHask: UNSAFE, may block.
486 then shoveString 0# xs
487 else constructErrorAndFail "writeLines"
489 shoveString (n +# 1#) xs
491 shoveString initPos# s
492 #endif /* ndef __HUGS__ */
495 #ifndef __PARALLEL_HASKELL__
496 writeBlocks :: ForeignObj -> Addr -> Int -> Int -> String -> IO ()
498 writeBlocks :: Addr -> Addr -> Int -> Int -> String -> IO ()
500 writeBlocks obj buf bufLen initPos s =
502 shoveString :: Int -> [Char] -> IO ()
507 At the end of a buffer write, update the buffer position
508 in the underlying file object, so that if the handle
509 is subsequently dropped by the program, the whole
510 buffer will be properly flushed.
512 There's one case where this delayed up-date of the buffer
513 position can go wrong: if a thread is killed, it might be
514 in the middle of filling up a buffer, with the result that
515 the partial buffer update is lost upon finalisation. However,
516 by the time killThread is supported, Haskell finalisers are also
517 likely to be in, which means the 'IOFileObject' hack can go
524 primWriteCharOffAddr buf n x
527 rc <- mayBlock obj (writeFileObject obj (n + 1)) -- ConcHask: UNSAFE, may block.
529 then shoveString 0 xs
530 else constructErrorAndFail "writeChunks"
532 shoveString (n + 1) xs
534 shoveString initPos s
535 #else /* ndef __HUGS__ */
536 #ifndef __PARALLEL_HASKELL__
537 writeBlocks :: ForeignObj -> Addr -> Int -> Int -> String -> IO ()
539 writeBlocks :: Addr -> Addr -> Int -> Int -> String -> IO ()
541 writeBlocks obj buf (I# bufLen) (I# initPos#) s =
543 write_char :: Addr -> Int# -> Char# -> IO ()
544 write_char (A# buf#) n# c# =
546 case (writeCharOffAddr# buf# n# c# s#) of s2# -> (# s2#, () #)
548 shoveString :: Int# -> [Char] -> IO ()
553 At the end of a buffer write, update the buffer position
554 in the underlying file object, so that if the handle
555 is subsequently dropped by the program, the whole
556 buffer will be properly flushed.
558 There's one case where this delayed up-date of the buffer
559 position can go wrong: if a thread is killed, it might be
560 in the middle of filling up a buffer, with the result that
561 the partial buffer update is lost upon finalisation. However,
562 by the time killThread is supported, Haskell finalisers are also
563 likely to be in, which means the 'IOFileObject' hack can go
567 setBufWPtr obj (I# n)
573 rc <- mayBlock obj (writeFileObject obj (I# (n +# 1#))) -- ConcHask: UNSAFE, may block.
575 then shoveString 0# xs
576 else constructErrorAndFail "writeChunks"
578 shoveString (n +# 1#) xs
580 shoveString initPos# s
581 #endif /* ndef __HUGS__ */
583 #ifndef __PARALLEL_HASKELL__
584 writeChars :: ForeignObj -> String -> IO ()
586 writeChars :: Addr -> String -> IO ()
588 writeChars _fo "" = return ()
589 writeChars fo (c:cs) = do
590 rc <- mayBlock fo (filePutc fo c) -- ConcHask: UNSAFE, may block.
592 then writeChars fo cs
593 else constructErrorAndFail "writeChars"
597 Computation @hPrint hdl t@ writes the string representation of {\em t}
598 given by the @shows@ function to the file or channel managed by {\em
601 [ Seem to have disappeared from the 1.4 interface - SOF 2/97 ]
604 hPrint :: Show a => Handle -> a -> IO ()
605 hPrint hdl = hPutStrLn hdl . show
608 Derived action @hPutStrLn hdl str@ writes the string \tr{str} to
609 the handle \tr{hdl}, adding a newline at the end.
612 hPutStrLn :: Handle -> String -> IO ()
613 hPutStrLn hndl str = do
620 %*********************************************************
622 \subsection{Try and bracket}
624 %*********************************************************
626 The construct @try comp@ exposes errors which occur within a
627 computation, and which are not fully handled. It always succeeds.
630 try :: IO a -> IO (Either IOError a)
631 try f = catch (do r <- f
635 bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c
636 bracket before after m = do
644 -- variant of the above where middle computation doesn't want x
645 bracket_ :: IO a -> (a -> IO b) -> IO c -> IO c
646 bracket_ before after m = do
655 %*********************************************************
657 \subsection{Standard IO}
659 %*********************************************************
661 The Prelude has from Day 1 provided a collection of common
662 IO functions. We define these here, but let the Prelude
666 putChar :: Char -> IO ()
667 putChar c = hPutChar stdout c
669 putStr :: String -> IO ()
670 putStr s = hPutStr stdout s
672 putStrLn :: String -> IO ()
673 putStrLn s = do putStr s
676 print :: Show a => a -> IO ()
677 print x = putStrLn (show x)
680 getChar = hGetChar stdin
683 getLine = hGetLine stdin
685 getContents :: IO String
686 getContents = hGetContents stdin
688 interact :: (String -> String) -> IO ()
689 interact f = do s <- getContents
692 readFile :: FilePath -> IO String
693 readFile name = openFile name ReadMode >>= hGetContents
695 writeFile :: FilePath -> String -> IO ()
696 writeFile name str = do
697 hdl <- openFile name WriteMode
701 appendFile :: FilePath -> String -> IO ()
702 appendFile name str = do
703 hdl <- openFile name AppendMode
707 readLn :: Read a => IO a
708 readLn = do l <- getLine
722 unimp s = error ("IO library: function not implemented: " ++ s)
724 type FILE_STAR = Addr
729 = Handle { name :: FilePath,
730 file :: FILE_STAR, -- C handle
731 mut :: IORef Handle_Mut, -- open/closed/semiclosed
737 = Handle_Mut { state :: HState
741 set_state :: Handle -> HState -> IO ()
742 set_state hdl new_state
743 = writeIORef (mut hdl) (Handle_Mut { state = new_state })
744 get_state :: Handle -> IO HState
746 = readIORef (mut hdl) >>= \m -> return (state m)
748 mkErr :: Handle -> String -> IO a
750 = do mut <- readIORef (mut h)
751 when (state mut /= HClosed)
752 (nh_close (file h) >> set_state h HClosed)
754 ioError (IOError msg)
759 file = unsafePerformIO nh_stdin,
760 mut = unsafePerformIO (newIORef (Handle_Mut { state = HOpen })),
767 file = unsafePerformIO nh_stdout,
768 mut = unsafePerformIO (newIORef (Handle_Mut { state = HOpen })),
775 file = unsafePerformIO nh_stderr,
776 mut = unsafePerformIO (newIORef (Handle_Mut { state = HOpen })),
781 instance Eq Handle where
782 h1 == h2 = file h1 == file h2
784 instance Show Handle where
785 showsPrec _ h = showString ("`" ++ name h ++ "'")
792 data IOMode = ReadMode | WriteMode | AppendMode | ReadWriteMode
793 deriving (Eq, Ord, Ix, Bounded, Enum, Read, Show)
795 data BufferMode = NoBuffering | LineBuffering
796 | BlockBuffering (Maybe Int)
797 deriving (Eq, Ord, Read, Show)
799 data SeekMode = AbsoluteSeek | RelativeSeek | SeekFromEnd
800 deriving (Eq, Ord, Ix, Bounded, Enum, Read, Show)
802 data HState = HOpen | HSemiClosed | HClosed
806 -- A global variable holding a list of all open handles.
807 -- Each handle is present as many times as it has been opened.
808 -- Any given file is allowed to have _either_ one writeable handle
809 -- or many readable handles in this list. The list is used to
810 -- enforce single-writer multiple reader semantics. It also
811 -- provides a list of handles for System.exitWith to flush and
812 -- close. In order not to have to put all this stuff in the
813 -- Prelude, System.exitWith merely runs prelExitWithAction,
814 -- which is originally Nothing, but which we set to Just ...
815 -- once handles appear in the list.
817 allHandles :: IORef [Handle]
818 allHandles = unsafePerformIO (newIORef [])
820 elemWriterHandles :: FilePath -> IO Bool
821 elemAllHandles :: FilePath -> IO Bool
822 addHandle :: Handle -> IO ()
823 delHandle :: Handle -> IO ()
824 cleanupHandles :: IO ()
827 = do hdls <- readIORef allHandles
828 mapM_ cleanupHandle hdls
833 >> nh_errno >>= \_ -> return ()
835 = nh_flush (file h) >> nh_close (file h)
836 >> nh_errno >>= \_ -> return ()
838 elemWriterHandles fname
839 = do hdls <- readIORef allHandles
840 let hdls_w = filter ((/= ReadMode).mode) hdls
841 return (fname `elem` (map name hdls_w))
844 = do hdls <- readIORef allHandles
845 return (fname `elem` (map name hdls))
848 = do cleanup_action <- readIORef prelCleanupAfterRunAction
849 case cleanup_action of
851 -> writeIORef prelCleanupAfterRunAction (Just cleanupHandles)
854 hdls <- readIORef allHandles
855 writeIORef allHandles (hdl : hdls)
858 = do hdls <- readIORef allHandles
859 let hdls' = takeWhile (/= hdl) hdls
860 ++ drop 1 (dropWhile (/= hdl) hdls)
861 writeIORef allHandles hdls'
865 openFile :: FilePath -> IOMode -> IO Handle
869 = (ioError.IOError) "openFile: empty file name"
872 = do not_ok <- elemWriterHandles f
874 then (ioError.IOError)
875 ("openFile: `" ++ f ++ "' in " ++ show mode
876 ++ ": is already open for writing")
877 else openFile_main f mode
880 = do not_ok <- elemAllHandles f
882 then (ioError.IOError)
883 ("openFile: `" ++ f ++ "' in " ++ show mode
884 ++ ": is already open for reading or writing")
885 else openFile_main f mode
888 = openFile_main f mode
891 = copy_String_to_cstring f >>= \nameptr ->
892 nh_open nameptr (mode2num mode) >>= \fh ->
895 then (ioError.IOError)
896 ("openFile: can't open <<" ++ f ++ ">> in " ++ show mode)
897 else do r <- newIORef (Handle_Mut { state = HOpen })
898 let hdl = Handle { name = f, file = fh,
899 mut = r, mode = mode }
903 mode2num :: IOMode -> Int
904 mode2num ReadMode = 0
905 mode2num WriteMode = 1
906 mode2num AppendMode = 2
907 mode2num ReadWriteMode
909 ("openFile <<" ++ f ++ ">>: ReadWriteMode not supported")
911 hClose :: Handle -> IO ()
913 = do mut <- readIORef (mut h)
914 if state mut == HClosed
916 ("hClose on closed handle " ++ show h)
918 do set_state h HClosed
925 ("hClose: error closing " ++ name h)
927 hGetContents :: Handle -> IO String
930 = mkErr h ("hGetContents on non-ReadMode handle " ++ show h)
932 = do mut <- readIORef (mut h)
933 if state mut /= HOpen
935 ("hGetContents on closed/semiclosed handle " ++ show h)
937 do set_state h HSemiClosed
941 = nh_read f >>= \ci ->
944 else read_all f >>= \rest ->
945 return ((primIntToChar ci):rest)
947 hPutStr :: Handle -> String -> IO ()
950 = mkErr h ("hPutStr on ReadMode handle " ++ show h)
952 = do mut <- readIORef (mut h)
953 if state mut /= HOpen
955 ("hPutStr on closed/semiclosed handle " ++ show h)
956 else write_all (file h) s
961 = nh_write f c >> write_all f cs
963 hFileSize :: Handle -> IO Integer
965 = do sz <- nh_filesize (file h)
968 then return (fromIntegral sz)
969 else mkErr h ("hFileSize on " ++ show h)
971 hIsEOF :: Handle -> IO Bool
973 = do iseof <- nh_iseof (file h)
976 then return (iseof /= 0)
977 else mkErr h ("hIsEOF on " ++ show h)
982 hSetBuffering :: Handle -> BufferMode -> IO ()
983 hSetBuffering = unimp "IO.hSetBuffering"
984 hGetBuffering :: Handle -> IO BufferMode
985 hGetBuffering = unimp "IO.hGetBuffering"
987 hFlush :: Handle -> IO ()
989 = do mut <- readIORef (mut h)
990 if state mut /= HOpen
992 ("hFlush on closed/semiclosed file " ++ name h)
993 else nh_flush (file h)
995 hGetPosn :: Handle -> IO HandlePosn
996 hGetPosn = unimp "IO.hGetPosn"
997 hSetPosn :: HandlePosn -> IO ()
998 hSetPosn = unimp "IO.hSetPosn"
999 hSeek :: Handle -> SeekMode -> Integer -> IO ()
1000 hSeek = unimp "IO.hSeek"
1001 hWaitForInput :: Handle -> Int -> IO Bool
1002 hWaitForInput = unimp "hWaitForInput"
1003 hReady :: Handle -> IO Bool
1004 hReady h = unimp "hReady" -- hWaitForInput h 0
1006 hGetChar :: Handle -> IO Char
1008 = nh_read (file h) >>= \ci ->
1009 return (primIntToChar ci)
1011 hGetLine :: Handle -> IO String
1012 hGetLine h = do c <- hGetChar h
1013 if c=='\n' then return ""
1014 else do cs <- hGetLine h
1017 hLookAhead :: Handle -> IO Char
1018 hLookAhead = unimp "IO.hLookAhead"
1021 hPutChar :: Handle -> Char -> IO ()
1022 hPutChar h c = hPutStr h [c]
1024 hPutStrLn :: Handle -> String -> IO ()
1025 hPutStrLn h s = do { hPutStr h s; hPutChar h '\n' }
1027 hPrint :: Show a => Handle -> a -> IO ()
1028 hPrint h = hPutStrLn h . show
1030 hIsOpen, hIsClosed, hIsReadable, hIsWritable :: Handle -> IO Bool
1031 hIsOpen h = do { s <- get_state h; return (s == HOpen) }
1032 hIsClosed h = do { s <- get_state h; return (s == HClosed) }
1033 hIsReadable h = return (mode h == ReadMode)
1034 hIsWritable h = return (mode h `elem` [WriteMode, AppendMode])
1036 hIsSeekable :: Handle -> IO Bool
1037 hIsSeekable = unimp "IO.hIsSeekable"
1040 isAlreadyExistsError,
1041 isDoesNotExistError,
1042 isAlreadyInUseError,
1046 isUserError :: IOError -> Bool
1048 isIllegalOperation = unimp "IO.isIllegalOperation"
1049 isAlreadyExistsError = unimp "IO.isAlreadyExistsError"
1050 isDoesNotExistError = unimp "IO.isDoesNotExistError"
1051 isAlreadyInUseError = unimp "IO.isAlreadyInUseError"
1052 isFullError = unimp "IO.isFullError"
1053 isEOFError = unimp "IO.isEOFError"
1054 isPermissionError = unimp "IO.isPermissionError"
1055 isUserError = unimp "IO.isUserError"
1058 ioeGetErrorString :: IOError -> String
1059 ioeGetErrorString = unimp "IO.ioeGetErrorString"
1060 ioeGetHandle :: IOError -> Maybe Handle
1061 ioeGetHandle = unimp "IO.ioeGetHandle"
1062 ioeGetFileName :: IOError -> Maybe FilePath
1063 ioeGetFileName = unimp "IO.ioeGetFileName"
1065 try :: IO a -> IO (Either IOError a)
1066 try p = catch (p >>= (return . Right)) (return . Left)
1068 bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c
1069 bracket before after m = do
1077 -- variant of the above where middle computation doesn't want x
1078 bracket_ :: IO a -> (a -> IO b) -> IO c -> IO c
1079 bracket_ before after m = do
1087 -- TODO: Hugs/slurpFile
1088 slurpFile = unimp "IO.slurpFile"
1091 #endif /* #ifndef __HUGS__ */