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 privileged Prelude ( IORef
92 , prelCleanupAfterRunAction
93 , copy_String_to_cstring
95 , primWriteCharOffAddr
120 import PrelHandle -- much of the real stuff is in here
122 import PrelRead ( readParen, Read(..), reads, lex,
126 import PrelMaybe ( Either(..), Maybe(..) )
127 import PrelAddr ( Addr(..), nullAddr )
128 import PrelByteArr ( ByteArray )
129 import PrelPack ( unpackNBytesAccST )
130 import PrelException ( ioError, catch )
133 #ifndef __PARALLEL_HASKELL__
134 import PrelForeign ( ForeignObj )
137 import Char ( ord, chr )
139 #endif /* ndef __HUGS__ */
143 %*********************************************************
145 \subsection{Simple input operations}
147 %*********************************************************
149 Computation @hReady hdl@ indicates whether at least
150 one item is available for input from handle {\em hdl}.
152 @hWaitForInput@ is the generalisation, wait for \tr{n} milliseconds
153 before deciding whether the Handle has run dry or not.
155 If @hWaitForInput@ finds anything in the Handle's buffer, it immediately returns.
156 If not, it tries to read from the underlying OS handle. Notice that
157 for buffered Handles connected to terminals this means waiting until a complete
161 hReady :: Handle -> IO Bool
162 hReady h = hWaitForInput h 0
164 hWaitForInput :: Handle -> Int -> IO Bool
165 hWaitForInput handle msecs =
166 wantReadableHandle "hWaitForInput" handle $ \ handle_ -> do
167 rc <- inputReady (haFO__ handle_) (msecs::Int) -- ConcHask: SAFE, won't block
171 _ -> constructErrorAndFail "hWaitForInput"
174 @hGetChar hdl@ reads the next character from handle @hdl@,
175 blocking until a character is available.
178 hGetChar :: Handle -> IO Char
180 c <- mayBlockRead "hGetChar" handle fileGetc
184 If EOF is reached before EOL is encountered, ignore the
185 EOF and return the partial line. Next attempt at calling
186 hGetLine on the handle will yield an EOF IO exception though.
188 hGetLine :: Handle -> IO String
202 if isEOFError err then
214 @hLookahead hdl@ returns the next character from handle @hdl@
215 without removing it from the input buffer, blocking until a
216 character is available.
219 hLookAhead :: Handle -> IO Char
220 hLookAhead handle = do
221 rc <- mayBlockRead "hLookAhead" handle fileLookAhead
226 %*********************************************************
228 \subsection{Getting the entire contents of a handle}
230 %*********************************************************
232 @hGetContents hdl@ returns the list of characters corresponding
233 to the unread portion of the channel or file managed by @hdl@,
234 which is made semi-closed.
237 hGetContents :: Handle -> IO String
238 hGetContents handle =
239 -- can't use wantReadableHandle here, because we want to side effect
241 withHandle handle $ \ handle_ -> do
242 case haType__ handle_ of
243 ErrorHandle theError -> ioError theError
244 ClosedHandle -> ioe_closedHandle "hGetContents" handle
245 SemiClosedHandle -> ioe_closedHandle "hGetContents" handle
246 AppendHandle -> ioError not_readable_error
247 WriteHandle -> ioError not_readable_error
250 To avoid introducing an extra layer of buffering here,
251 we provide three lazy read methods, based on character,
252 line, and block buffering.
254 let handle_' = handle_{ haType__ = SemiClosedHandle }
255 case (haBufferMode__ handle_) of
257 str <- unsafeInterleaveIO (lazyReadLine handle (haFO__ handle_))
258 return (handle_', str)
259 BlockBuffering _ -> do
260 str <- unsafeInterleaveIO (lazyReadBlock handle (haFO__ handle_))
261 return (handle_', str)
263 str <- unsafeInterleaveIO (lazyReadChar handle (haFO__ handle_))
264 return (handle_', str)
267 IOError (Just handle) IllegalOperation "hGetContents"
268 ("handle is not open for reading")
271 Note that someone may close the semi-closed handle (or change its buffering),
272 so each these lazy read functions are pulled on, they have to check whether
273 the handle has indeed been closed.
276 #ifndef __PARALLEL_HASKELL__
277 lazyReadBlock :: Handle -> ForeignObj -> IO String
278 lazyReadLine :: Handle -> ForeignObj -> IO String
279 lazyReadChar :: Handle -> ForeignObj -> IO String
281 lazyReadBlock :: Handle -> Addr -> IO String
282 lazyReadLine :: Handle -> Addr -> IO String
283 lazyReadChar :: Handle -> Addr -> IO String
286 lazyReadBlock handle fo = do
287 buf <- getBufStart fo 0
288 bytes <- mayBlock fo (readBlock fo) -- ConcHask: UNSAFE, may block.
290 -3 -> -- buffering has been turned off, use lazyReadChar instead
291 lazyReadChar handle fo
293 -1 -> -- an error occurred, close the handle
294 withHandle handle $ \ handle_ -> do
295 closeFile (haFO__ handle_) 0{-don't bother flushing-} -- ConcHask: SAFE, won't block.
296 return (handle_ { haType__ = ClosedHandle,
297 haFO__ = nullFile__ },
300 more <- unsafeInterleaveIO (lazyReadBlock handle fo)
301 stToIO (unpackNBytesAccST buf bytes more)
303 lazyReadLine handle fo = do
304 bytes <- mayBlock fo (readLine fo) -- ConcHask: UNSAFE, may block.
306 -3 -> -- buffering has been turned off, use lazyReadChar instead
307 lazyReadChar handle fo
308 -2 -> return "" -- handle closed by someone else, stop reading.
309 -1 -> -- an error occurred, close the handle
310 withHandle handle $ \ handle_ -> do
311 closeFile (haFO__ handle_) 0{- don't bother flushing-} -- ConcHask: SAFE, won't block
312 return (handle_ { haType__ = ClosedHandle,
313 haFO__ = nullFile__ },
316 more <- unsafeInterleaveIO (lazyReadLine handle fo)
317 buf <- getBufStart fo bytes -- ConcHask: won't block
318 stToIO (unpackNBytesAccST buf bytes more)
320 lazyReadChar handle fo = do
321 char <- mayBlock fo (readChar fo) -- ConcHask: UNSAFE, may block.
323 -4 -> -- buffering is now block-buffered, use lazyReadBlock instead
324 lazyReadBlock handle fo
326 -3 -> -- buffering is now line-buffered, use lazyReadLine instead
327 lazyReadLine handle fo
329 -1 -> -- error, silently close handle.
330 withHandle handle $ \ handle_ -> do
331 closeFile (haFO__ handle_) 0{-don't bother flusing-} -- ConcHask: SAFE, won't block
332 return (handle_{ haType__ = ClosedHandle,
333 haFO__ = nullFile__ },
336 more <- unsafeInterleaveIO (lazyReadChar handle fo)
337 return (chr char : more)
342 %*********************************************************
344 \subsection{Simple output functions}
346 %*********************************************************
348 @hPutChar hdl ch@ writes the character @ch@ to the file
349 or channel managed by @hdl@. Characters may be buffered if
350 buffering is enabled for @hdl@
353 hPutChar :: Handle -> Char -> IO ()
355 wantWriteableHandle "hPutChar" handle $ \ handle_ -> do
356 let fo = haFO__ handle_
358 rc <- mayBlock fo (filePutc fo c) -- ConcHask: UNSAFE, may block.
361 else constructErrorAndFail "hPutChar"
365 @hPutStr hdl s@ writes the string @s@ to the file or
366 channel managed by @hdl@, buffering the output if needs be.
369 hPutStr :: Handle -> String -> IO ()
371 wantWriteableHandle "hPutStr" handle $ \ handle_ -> do
372 let fo = haFO__ handle_
374 case haBufferMode__ handle_ of
376 buf <- getWriteableBuf fo
379 writeLines fo buf bsz pos str
380 BlockBuffering _ -> do
381 buf <- getWriteableBuf fo
384 writeBlocks fo buf bsz pos str
389 Going across the border between Haskell and C is relatively costly,
390 so for block writes we pack the character strings on the Haskell-side
391 before passing the external write routine a pointer to the buffer.
396 #ifdef __CONCURRENT_HASKELL__
397 /* See comment in shoveString below for explanation */
398 #warning delayed update of buffer disnae work with killThread
401 #ifndef __PARALLEL_HASKELL__
402 writeLines :: ForeignObj -> Addr -> Int -> Int -> String -> IO ()
404 writeLines :: Addr -> Addr -> Int -> Int -> String -> IO ()
406 writeLines obj buf bufLen initPos s =
408 shoveString :: Int -> [Char] -> IO ()
413 At the end of a buffer write, update the buffer position
414 in the underlying file object, so that if the handle
415 is subsequently dropped by the program, the whole
416 buffer will be properly flushed.
418 There's one case where this delayed up-date of the buffer
419 position can go wrong: if a thread is killed, it might be
420 in the middle of filling up a buffer, with the result that
421 the partial buffer update is lost upon finalisation. Not
422 that killing of threads is supported at the moment.
428 primWriteCharOffAddr buf n x
429 {- Flushing on buffer exhaustion or newlines (even if it isn't the last one) -}
430 if n == bufLen || x == '\n'
432 rc <- mayBlock obj (writeFileObject obj (n + 1)) -- ConcHask: UNSAFE, may block.
434 then shoveString 0 xs
435 else constructErrorAndFail "writeLines"
437 shoveString (n + 1) xs
439 shoveString initPos s
440 #else /* ndef __HUGS__ */
441 #ifndef __PARALLEL_HASKELL__
442 writeLines :: ForeignObj -> Addr -> Int -> Int -> String -> IO ()
444 writeLines :: Addr -> Addr -> Int -> Int -> String -> IO ()
446 writeLines obj buf (I# bufLen) (I# initPos#) s =
448 write_char :: Addr -> Int# -> Char# -> IO ()
449 write_char (A# buf#) n# c# =
451 case (writeCharOffAddr# buf# n# c# s#) of s2# -> (# s2#, () #)
453 shoveString :: Int# -> [Char] -> IO ()
458 At the end of a buffer write, update the buffer position
459 in the underlying file object, so that if the handle
460 is subsequently dropped by the program, the whole
461 buffer will be properly flushed.
463 There's one case where this delayed up-date of the buffer
464 position can go wrong: if a thread is killed, it might be
465 in the middle of filling up a buffer, with the result that
466 the partial buffer update is lost upon finalisation. Not
467 that killing of threads is supported at the moment.
470 setBufWPtr obj (I# n)
474 {- Flushing on buffer exhaustion or newlines (even if it isn't the last one) -}
475 if n ==# bufLen || x `eqChar#` '\n'#
477 rc <- mayBlock obj (writeFileObject obj (I# (n +# 1#))) -- ConcHask: UNSAFE, may block.
479 then shoveString 0# xs
480 else constructErrorAndFail "writeLines"
482 shoveString (n +# 1#) xs
484 shoveString initPos# s
485 #endif /* ndef __HUGS__ */
488 #ifndef __PARALLEL_HASKELL__
489 writeBlocks :: ForeignObj -> Addr -> Int -> Int -> String -> IO ()
491 writeBlocks :: Addr -> Addr -> Int -> Int -> String -> IO ()
493 writeBlocks obj buf bufLen initPos s =
495 shoveString :: Int -> [Char] -> IO ()
500 At the end of a buffer write, update the buffer position
501 in the underlying file object, so that if the handle
502 is subsequently dropped by the program, the whole
503 buffer will be properly flushed.
505 There's one case where this delayed up-date of the buffer
506 position can go wrong: if a thread is killed, it might be
507 in the middle of filling up a buffer, with the result that
508 the partial buffer update is lost upon finalisation. However,
509 by the time killThread is supported, Haskell finalisers are also
510 likely to be in, which means the 'IOFileObject' hack can go
517 primWriteCharOffAddr buf n x
520 rc <- mayBlock obj (writeFileObject obj (n + 1)) -- ConcHask: UNSAFE, may block.
522 then shoveString 0 xs
523 else constructErrorAndFail "writeChunks"
525 shoveString (n + 1) xs
527 shoveString initPos s
528 #else /* ndef __HUGS__ */
529 #ifndef __PARALLEL_HASKELL__
530 writeBlocks :: ForeignObj -> Addr -> Int -> Int -> String -> IO ()
532 writeBlocks :: Addr -> Addr -> Int -> Int -> String -> IO ()
534 writeBlocks obj buf (I# bufLen) (I# initPos#) s =
536 write_char :: Addr -> Int# -> Char# -> IO ()
537 write_char (A# buf#) n# c# =
539 case (writeCharOffAddr# buf# n# c# s#) of s2# -> (# s2#, () #)
541 shoveString :: Int# -> [Char] -> IO ()
546 At the end of a buffer write, update the buffer position
547 in the underlying file object, so that if the handle
548 is subsequently dropped by the program, the whole
549 buffer will be properly flushed.
551 There's one case where this delayed up-date of the buffer
552 position can go wrong: if a thread is killed, it might be
553 in the middle of filling up a buffer, with the result that
554 the partial buffer update is lost upon finalisation. However,
555 by the time killThread is supported, Haskell finalisers are also
556 likely to be in, which means the 'IOFileObject' hack can go
560 setBufWPtr obj (I# n)
566 rc <- mayBlock obj (writeFileObject obj (I# (n +# 1#))) -- ConcHask: UNSAFE, may block.
568 then shoveString 0# xs
569 else constructErrorAndFail "writeChunks"
571 shoveString (n +# 1#) xs
573 shoveString initPos# s
574 #endif /* ndef __HUGS__ */
576 #ifndef __PARALLEL_HASKELL__
577 writeChars :: ForeignObj -> String -> IO ()
579 writeChars :: Addr -> String -> IO ()
581 writeChars _fo "" = return ()
582 writeChars fo (c:cs) = do
583 rc <- mayBlock fo (filePutc fo c) -- ConcHask: UNSAFE, may block.
585 then writeChars fo cs
586 else constructErrorAndFail "writeChars"
590 Computation @hPrint hdl t@ writes the string representation of {\em t}
591 given by the @shows@ function to the file or channel managed by {\em
594 [ Seem to have disappeared from the 1.4 interface - SOF 2/97 ]
597 hPrint :: Show a => Handle -> a -> IO ()
598 hPrint hdl = hPutStrLn hdl . show
601 Derived action @hPutStrLn hdl str@ writes the string \tr{str} to
602 the handle \tr{hdl}, adding a newline at the end.
605 hPutStrLn :: Handle -> String -> IO ()
606 hPutStrLn hndl str = do
613 %*********************************************************
615 \subsection{Try and bracket}
617 %*********************************************************
619 The construct @try comp@ exposes errors which occur within a
620 computation, and which are not fully handled. It always succeeds.
623 try :: IO a -> IO (Either IOError a)
624 try f = catch (do r <- f
628 bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c
629 bracket before after m = do
637 -- variant of the above where middle computation doesn't want x
638 bracket_ :: IO a -> (a -> IO b) -> IO c -> IO c
639 bracket_ before after m = do
648 %*********************************************************
650 \subsection{Standard IO}
652 %*********************************************************
654 The Prelude has from Day 1 provided a collection of common
655 IO functions. We define these here, but let the Prelude
659 putChar :: Char -> IO ()
660 putChar c = hPutChar stdout c
662 putStr :: String -> IO ()
663 putStr s = hPutStr stdout s
665 putStrLn :: String -> IO ()
666 putStrLn s = do putStr s
669 print :: Show a => a -> IO ()
670 print x = putStrLn (show x)
673 getChar = hGetChar stdin
676 getLine = hGetLine stdin
678 getContents :: IO String
679 getContents = hGetContents stdin
681 interact :: (String -> String) -> IO ()
682 interact f = do s <- getContents
685 readFile :: FilePath -> IO String
686 readFile name = openFile name ReadMode >>= hGetContents
688 writeFile :: FilePath -> String -> IO ()
689 writeFile name str = do
690 hdl <- openFile name WriteMode
694 appendFile :: FilePath -> String -> IO ()
695 appendFile name str = do
696 hdl <- openFile name AppendMode
700 readLn :: Read a => IO a
701 readLn = do l <- getLine
715 unimp s = error ("IO library: function not implemented: " ++ s)
717 type FILE_STAR = Addr
722 = Handle { name :: FilePath,
723 file :: FILE_STAR, -- C handle
724 mut :: IORef Handle_Mut, -- open/closed/semiclosed
730 = Handle_Mut { state :: HState
734 set_state :: Handle -> HState -> IO ()
735 set_state hdl new_state
736 = writeIORef (mut hdl) (Handle_Mut { state = new_state })
737 get_state :: Handle -> IO HState
739 = readIORef (mut hdl) >>= \m -> return (state m)
741 mkErr :: Handle -> String -> IO a
743 = do mut <- readIORef (mut h)
744 when (state mut /= HClosed)
745 (nh_close (file h) >> set_state h HClosed)
747 ioError (IOError msg)
752 file = unsafePerformIO nh_stdin,
753 mut = unsafePerformIO (newIORef (Handle_Mut { state = HOpen })),
760 file = unsafePerformIO nh_stdout,
761 mut = unsafePerformIO (newIORef (Handle_Mut { state = HOpen })),
768 file = unsafePerformIO nh_stderr,
769 mut = unsafePerformIO (newIORef (Handle_Mut { state = HOpen })),
774 instance Eq Handle where
775 h1 == h2 = file h1 == file h2
777 instance Show Handle where
778 showsPrec _ h = showString ("`" ++ name h ++ "'")
785 data IOMode = ReadMode | WriteMode | AppendMode | ReadWriteMode
786 deriving (Eq, Ord, Ix, Bounded, Enum, Read, Show)
788 data BufferMode = NoBuffering | LineBuffering
789 | BlockBuffering (Maybe Int)
790 deriving (Eq, Ord, Read, Show)
792 data SeekMode = AbsoluteSeek | RelativeSeek | SeekFromEnd
793 deriving (Eq, Ord, Ix, Bounded, Enum, Read, Show)
795 data HState = HOpen | HSemiClosed | HClosed
799 -- A global variable holding a list of all open handles.
800 -- Each handle is present as many times as it has been opened.
801 -- Any given file is allowed to have _either_ one writeable handle
802 -- or many readable handles in this list. The list is used to
803 -- enforce single-writer multiple reader semantics. It also
804 -- provides a list of handles for System.exitWith to flush and
805 -- close. In order not to have to put all this stuff in the
806 -- Prelude, System.exitWith merely runs prelExitWithAction,
807 -- which is originally Nothing, but which we set to Just ...
808 -- once handles appear in the list.
810 allHandles :: IORef [Handle]
811 allHandles = unsafePerformIO (newIORef [])
813 elemWriterHandles :: FilePath -> IO Bool
814 elemAllHandles :: FilePath -> IO Bool
815 addHandle :: Handle -> IO ()
816 delHandle :: Handle -> IO ()
817 cleanupHandles :: IO ()
820 = do hdls <- readIORef allHandles
821 mapM_ cleanupHandle hdls
826 >> nh_errno >>= \_ -> return ()
828 = nh_flush (file h) >> nh_close (file h)
829 >> nh_errno >>= \_ -> return ()
831 elemWriterHandles fname
832 = do hdls <- readIORef allHandles
833 let hdls_w = filter ((/= ReadMode).mode) hdls
834 return (fname `elem` (map name hdls_w))
837 = do hdls <- readIORef allHandles
838 return (fname `elem` (map name hdls))
841 = do cleanup_action <- readIORef prelCleanupAfterRunAction
842 case cleanup_action of
844 -> writeIORef prelCleanupAfterRunAction (Just cleanupHandles)
847 hdls <- readIORef allHandles
848 writeIORef allHandles (hdl : hdls)
851 = do hdls <- readIORef allHandles
852 let hdls' = takeWhile (/= hdl) hdls
853 ++ drop 1 (dropWhile (/= hdl) hdls)
854 writeIORef allHandles hdls'
858 openFile :: FilePath -> IOMode -> IO Handle
862 = (ioError.IOError) "openFile: empty file name"
865 = do not_ok <- elemWriterHandles f
867 then (ioError.IOError)
868 ("openFile: `" ++ f ++ "' in " ++ show mode
869 ++ ": is already open for writing")
870 else openFile_main f mode
873 = do not_ok <- elemAllHandles f
875 then (ioError.IOError)
876 ("openFile: `" ++ f ++ "' in " ++ show mode
877 ++ ": is already open for reading or writing")
878 else openFile_main f mode
881 = openFile_main f mode
884 = copy_String_to_cstring f >>= \nameptr ->
885 nh_open nameptr (mode2num mode) >>= \fh ->
888 then (ioError.IOError)
889 ("openFile: can't open <<" ++ f ++ ">> in " ++ show mode)
890 else do r <- newIORef (Handle_Mut { state = HOpen })
891 let hdl = Handle { name = f, file = fh,
892 mut = r, mode = mode }
896 mode2num :: IOMode -> Int
897 mode2num ReadMode = 0
898 mode2num WriteMode = 1
899 mode2num AppendMode = 2
900 mode2num ReadWriteMode
902 ("openFile <<" ++ f ++ ">>: ReadWriteMode not supported")
904 hClose :: Handle -> IO ()
906 = do mut <- readIORef (mut h)
907 if state mut == HClosed
909 ("hClose on closed handle " ++ show h)
911 do set_state h HClosed
918 ("hClose: error closing " ++ name h)
920 hGetContents :: Handle -> IO String
923 = mkErr h ("hGetContents on non-ReadMode handle " ++ show h)
925 = do mut <- readIORef (mut h)
926 if state mut /= HOpen
928 ("hGetContents on closed/semiclosed handle " ++ show h)
930 do set_state h HSemiClosed
934 = nh_read f >>= \ci ->
937 else read_all f >>= \rest ->
938 return ((primIntToChar ci):rest)
940 hPutStr :: Handle -> String -> IO ()
943 = mkErr h ("hPutStr on ReadMode handle " ++ show h)
945 = do mut <- readIORef (mut h)
946 if state mut /= HOpen
948 ("hPutStr on closed/semiclosed handle " ++ show h)
949 else write_all (file h) s
954 = nh_write f c >> write_all f cs
956 hFileSize :: Handle -> IO Integer
958 = do sz <- nh_filesize (file h)
961 then return (fromIntegral sz)
962 else mkErr h ("hFileSize on " ++ show h)
964 hIsEOF :: Handle -> IO Bool
966 = do iseof <- nh_iseof (file h)
969 then return (iseof /= 0)
970 else mkErr h ("hIsEOF on " ++ show h)
975 hSetBuffering :: Handle -> BufferMode -> IO ()
976 hSetBuffering = unimp "IO.hSetBuffering"
977 hGetBuffering :: Handle -> IO BufferMode
978 hGetBuffering = unimp "IO.hGetBuffering"
980 hFlush :: Handle -> IO ()
982 = do mut <- readIORef (mut h)
983 if state mut /= HOpen
985 ("hFlush on closed/semiclosed file " ++ name h)
986 else nh_flush (file h)
988 hGetPosn :: Handle -> IO HandlePosn
989 hGetPosn = unimp "IO.hGetPosn"
990 hSetPosn :: HandlePosn -> IO ()
991 hSetPosn = unimp "IO.hSetPosn"
992 hSeek :: Handle -> SeekMode -> Integer -> IO ()
993 hSeek = unimp "IO.hSeek"
994 hWaitForInput :: Handle -> Int -> IO Bool
995 hWaitForInput = unimp "hWaitForInput"
996 hReady :: Handle -> IO Bool
997 hReady h = unimp "hReady" -- hWaitForInput h 0
999 hGetChar :: Handle -> IO Char
1001 = nh_read (file h) >>= \ci ->
1002 return (primIntToChar ci)
1004 hGetLine :: Handle -> IO String
1005 hGetLine h = do c <- hGetChar h
1006 if c=='\n' then return ""
1007 else do cs <- hGetLine h
1010 hLookAhead :: Handle -> IO Char
1011 hLookAhead = unimp "IO.hLookAhead"
1014 hPutChar :: Handle -> Char -> IO ()
1015 hPutChar h c = hPutStr h [c]
1017 hPutStrLn :: Handle -> String -> IO ()
1018 hPutStrLn h s = do { hPutStr h s; hPutChar h '\n' }
1020 hPrint :: Show a => Handle -> a -> IO ()
1021 hPrint h = hPutStrLn h . show
1023 hIsOpen, hIsClosed, hIsReadable, hIsWritable :: Handle -> IO Bool
1024 hIsOpen h = do { s <- get_state h; return (s == HOpen) }
1025 hIsClosed h = do { s <- get_state h; return (s == HClosed) }
1026 hIsReadable h = return (mode h == ReadMode)
1027 hIsWritable h = return (mode h `elem` [WriteMode, AppendMode])
1029 hIsSeekable :: Handle -> IO Bool
1030 hIsSeekable = unimp "IO.hIsSeekable"
1033 isAlreadyExistsError,
1034 isDoesNotExistError,
1035 isAlreadyInUseError,
1039 isUserError :: IOError -> Bool
1041 isIllegalOperation = unimp "IO.isIllegalOperation"
1042 isAlreadyExistsError = unimp "IO.isAlreadyExistsError"
1043 isDoesNotExistError = unimp "IO.isDoesNotExistError"
1044 isAlreadyInUseError = unimp "IO.isAlreadyInUseError"
1045 isFullError = unimp "IO.isFullError"
1046 isEOFError = unimp "IO.isEOFError"
1047 isPermissionError = unimp "IO.isPermissionError"
1048 isUserError = unimp "IO.isUserError"
1051 ioeGetErrorString :: IOError -> String
1052 ioeGetErrorString = unimp "IO.ioeGetErrorString"
1053 ioeGetHandle :: IOError -> Maybe Handle
1054 ioeGetHandle = unimp "IO.ioeGetHandle"
1055 ioeGetFileName :: IOError -> Maybe FilePath
1056 ioeGetFileName = unimp "IO.ioeGetFileName"
1058 try :: IO a -> IO (Either IOError a)
1059 try p = catch (p >>= (return . Right)) (return . Left)
1061 bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c
1062 bracket before after m = do
1070 -- variant of the above where middle computation doesn't want x
1071 bracket_ :: IO a -> (a -> IO b) -> IO c -> IO c
1072 bracket_ before after m = do
1080 -- TODO: Hugs/slurpFile
1081 slurpFile = unimp "IO.slurpFile"
1084 #endif /* #ifndef __HUGS__ */