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
98 import privileged Prelude ( IORef
100 , prelCleanupAfterRunAction
101 , copy_String_to_cstring
103 , primWriteCharOffAddr
128 import PrelHandle -- much of the real stuff is in here
130 import PrelRead ( readParen, Read(..), reads, lex,
134 import PrelMaybe ( Either(..), Maybe(..) )
135 import PrelAddr ( Addr(..), nullAddr )
136 import PrelByteArr ( ByteArray )
137 import PrelPack ( unpackNBytesAccST )
138 import PrelException ( ioError, catch )
141 #ifndef __PARALLEL_HASKELL__
142 import PrelForeign ( ForeignObj )
145 import Char ( ord, chr )
147 #endif /* ndef __HUGS__ */
151 %*********************************************************
153 \subsection{Simple input operations}
155 %*********************************************************
157 Computation @hReady hdl@ indicates whether at least
158 one item is available for input from handle {\em hdl}.
160 @hWaitForInput@ is the generalisation, wait for \tr{n} milliseconds
161 before deciding whether the Handle has run dry or not.
163 If @hWaitForInput@ finds anything in the Handle's buffer, it immediately returns.
164 If not, it tries to read from the underlying OS handle. Notice that
165 for buffered Handles connected to terminals this means waiting until a complete
169 hReady :: Handle -> IO Bool
170 hReady h = hWaitForInput h 0
172 hWaitForInput :: Handle -> Int -> IO Bool
173 hWaitForInput handle msecs =
174 wantReadableHandle "hWaitForInput" handle $ \ handle_ -> do
175 rc <- inputReady (haFO__ handle_) (msecs::Int) -- ConcHask: SAFE, won't block
179 _ -> constructErrorAndFail "hWaitForInput"
182 @hGetChar hdl@ reads the next character from handle @hdl@,
183 blocking until a character is available.
186 hGetChar :: Handle -> IO Char
188 c <- mayBlockRead "hGetChar" handle fileGetc
192 If EOF is reached before EOL is encountered, ignore the
193 EOF and return the partial line. Next attempt at calling
194 hGetLine on the handle will yield an EOF IO exception though.
196 hGetLine :: Handle -> IO String
210 if isEOFError err then
222 @hLookahead hdl@ returns the next character from handle @hdl@
223 without removing it from the input buffer, blocking until a
224 character is available.
227 hLookAhead :: Handle -> IO Char
228 hLookAhead handle = do
229 rc <- mayBlockRead "hLookAhead" handle fileLookAhead
234 %*********************************************************
236 \subsection{Getting the entire contents of a handle}
238 %*********************************************************
240 @hGetContents hdl@ returns the list of characters corresponding
241 to the unread portion of the channel or file managed by @hdl@,
242 which is made semi-closed.
245 hGetContents :: Handle -> IO String
246 hGetContents handle =
247 -- can't use wantReadableHandle here, because we want to side effect
249 withHandle handle $ \ handle_ -> do
250 case haType__ handle_ of
251 ErrorHandle theError -> ioError theError
252 ClosedHandle -> ioe_closedHandle "hGetContents" handle
253 SemiClosedHandle -> ioe_closedHandle "hGetContents" handle
254 AppendHandle -> ioError not_readable_error
255 WriteHandle -> ioError not_readable_error
258 To avoid introducing an extra layer of buffering here,
259 we provide three lazy read methods, based on character,
260 line, and block buffering.
262 let handle_' = handle_{ haType__ = SemiClosedHandle }
263 case (haBufferMode__ handle_) of
265 str <- unsafeInterleaveIO (lazyReadLine handle (haFO__ handle_))
266 return (handle_', str)
267 BlockBuffering _ -> do
268 str <- unsafeInterleaveIO (lazyReadBlock handle (haFO__ handle_))
269 return (handle_', str)
271 str <- unsafeInterleaveIO (lazyReadChar handle (haFO__ handle_))
272 return (handle_', str)
275 IOError (Just handle) IllegalOperation "hGetContents"
276 ("handle is not open for reading")
279 Note that someone may close the semi-closed handle (or change its buffering),
280 so each these lazy read functions are pulled on, they have to check whether
281 the handle has indeed been closed.
284 #ifndef __PARALLEL_HASKELL__
285 lazyReadBlock :: Handle -> ForeignObj -> IO String
286 lazyReadLine :: Handle -> ForeignObj -> IO String
287 lazyReadChar :: Handle -> ForeignObj -> IO String
289 lazyReadBlock :: Handle -> Addr -> IO String
290 lazyReadLine :: Handle -> Addr -> IO String
291 lazyReadChar :: Handle -> Addr -> IO String
294 lazyReadBlock handle fo = do
295 buf <- getBufStart fo 0
296 bytes <- mayBlock fo (readBlock fo) -- ConcHask: UNSAFE, may block.
298 -3 -> -- buffering has been turned off, use lazyReadChar instead
299 lazyReadChar handle fo
301 -1 -> -- an error occurred, close the handle
302 withHandle handle $ \ handle_ -> do
303 closeFile (haFO__ handle_) 0{-don't bother flushing-} -- ConcHask: SAFE, won't block.
304 return (handle_ { haType__ = ClosedHandle,
305 haFO__ = nullFile__ },
308 more <- unsafeInterleaveIO (lazyReadBlock handle fo)
309 stToIO (unpackNBytesAccST buf bytes more)
311 lazyReadLine handle fo = do
312 bytes <- mayBlock fo (readLine fo) -- ConcHask: UNSAFE, may block.
314 -3 -> -- buffering has been turned off, use lazyReadChar instead
315 lazyReadChar handle fo
316 -2 -> return "" -- handle closed by someone else, stop reading.
317 -1 -> -- an error occurred, close the handle
318 withHandle handle $ \ handle_ -> do
319 closeFile (haFO__ handle_) 0{- don't bother flushing-} -- ConcHask: SAFE, won't block
320 return (handle_ { haType__ = ClosedHandle,
321 haFO__ = nullFile__ },
324 more <- unsafeInterleaveIO (lazyReadLine handle fo)
325 buf <- getBufStart fo bytes -- ConcHask: won't block
326 stToIO (unpackNBytesAccST buf bytes more)
328 lazyReadChar handle fo = do
329 char <- mayBlock fo (readChar fo) -- ConcHask: UNSAFE, may block.
331 -4 -> -- buffering is now block-buffered, use lazyReadBlock instead
332 lazyReadBlock handle fo
334 -3 -> -- buffering is now line-buffered, use lazyReadLine instead
335 lazyReadLine handle fo
337 -1 -> -- error, silently close handle.
338 withHandle handle $ \ handle_ -> do
339 closeFile (haFO__ handle_) 0{-don't bother flusing-} -- ConcHask: SAFE, won't block
340 return (handle_{ haType__ = ClosedHandle,
341 haFO__ = nullFile__ },
344 more <- unsafeInterleaveIO (lazyReadChar handle fo)
345 return (chr char : more)
350 %*********************************************************
352 \subsection{Simple output functions}
354 %*********************************************************
356 @hPutChar hdl ch@ writes the character @ch@ to the file
357 or channel managed by @hdl@. Characters may be buffered if
358 buffering is enabled for @hdl@
361 hPutChar :: Handle -> Char -> IO ()
363 wantWriteableHandle "hPutChar" handle $ \ handle_ -> do
364 let fo = haFO__ handle_
366 rc <- mayBlock fo (filePutc fo c) -- ConcHask: UNSAFE, may block.
369 else constructErrorAndFail "hPutChar"
373 @hPutStr hdl s@ writes the string @s@ to the file or
374 channel managed by @hdl@, buffering the output if needs be.
377 hPutStr :: Handle -> String -> IO ()
379 wantWriteableHandle "hPutStr" handle $ \ handle_ -> do
380 let fo = haFO__ handle_
382 case haBufferMode__ handle_ of
384 buf <- getWriteableBuf fo
387 writeLines fo buf bsz pos str
388 BlockBuffering _ -> do
389 buf <- getWriteableBuf fo
392 writeBlocks fo buf bsz pos str
397 Going across the border between Haskell and C is relatively costly,
398 so for block writes we pack the character strings on the Haskell-side
399 before passing the external write routine a pointer to the buffer.
404 #ifdef __CONCURRENT_HASKELL__
405 /* See comment in shoveString below for explanation */
406 #warning delayed update of buffer disnae work with killThread
409 #ifndef __PARALLEL_HASKELL__
410 writeLines :: ForeignObj -> Addr -> Int -> Int -> String -> IO ()
412 writeLines :: Addr -> Addr -> Int -> Int -> String -> IO ()
414 writeLines obj buf bufLen initPos s =
416 shoveString :: Int -> [Char] -> IO ()
421 At the end of a buffer write, update the buffer position
422 in the underlying file object, so that if the handle
423 is subsequently dropped by the program, the whole
424 buffer will be properly flushed.
426 There's one case where this delayed up-date of the buffer
427 position can go wrong: if a thread is killed, it might be
428 in the middle of filling up a buffer, with the result that
429 the partial buffer update is lost upon finalisation. Not
430 that killing of threads is supported at the moment.
436 primWriteCharOffAddr buf n x
437 {- Flushing on buffer exhaustion or newlines (even if it isn't the last one) -}
438 if n == bufLen || x == '\n'
440 rc <- mayBlock obj (writeFileObject obj (n + 1)) -- ConcHask: UNSAFE, may block.
442 then shoveString 0 xs
443 else constructErrorAndFail "writeLines"
445 shoveString (n + 1) xs
447 shoveString initPos s
448 #else /* ndef __HUGS__ */
449 #ifndef __PARALLEL_HASKELL__
450 writeLines :: ForeignObj -> Addr -> Int -> Int -> String -> IO ()
452 writeLines :: Addr -> Addr -> Int -> Int -> String -> IO ()
454 writeLines obj buf (I# bufLen) (I# initPos#) s =
456 write_char :: Addr -> Int# -> Char# -> IO ()
457 write_char (A# buf#) n# c# =
459 case (writeCharOffAddr# buf# n# c# s#) of s2# -> (# s2#, () #)
461 shoveString :: Int# -> [Char] -> IO ()
466 At the end of a buffer write, update the buffer position
467 in the underlying file object, so that if the handle
468 is subsequently dropped by the program, the whole
469 buffer will be properly flushed.
471 There's one case where this delayed up-date of the buffer
472 position can go wrong: if a thread is killed, it might be
473 in the middle of filling up a buffer, with the result that
474 the partial buffer update is lost upon finalisation. Not
475 that killing of threads is supported at the moment.
478 setBufWPtr obj (I# n)
482 {- Flushing on buffer exhaustion or newlines (even if it isn't the last one) -}
483 if n ==# bufLen || x `eqChar#` '\n'#
485 rc <- mayBlock obj (writeFileObject obj (I# (n +# 1#))) -- ConcHask: UNSAFE, may block.
487 then shoveString 0# xs
488 else constructErrorAndFail "writeLines"
490 shoveString (n +# 1#) xs
492 shoveString initPos# s
493 #endif /* ndef __HUGS__ */
496 #ifndef __PARALLEL_HASKELL__
497 writeBlocks :: ForeignObj -> Addr -> Int -> Int -> String -> IO ()
499 writeBlocks :: Addr -> Addr -> Int -> Int -> String -> IO ()
501 writeBlocks obj buf bufLen initPos s =
503 shoveString :: Int -> [Char] -> IO ()
508 At the end of a buffer write, update the buffer position
509 in the underlying file object, so that if the handle
510 is subsequently dropped by the program, the whole
511 buffer will be properly flushed.
513 There's one case where this delayed up-date of the buffer
514 position can go wrong: if a thread is killed, it might be
515 in the middle of filling up a buffer, with the result that
516 the partial buffer update is lost upon finalisation. However,
517 by the time killThread is supported, Haskell finalisers are also
518 likely to be in, which means the 'IOFileObject' hack can go
525 primWriteCharOffAddr buf n x
528 rc <- mayBlock obj (writeFileObject obj (n + 1)) -- ConcHask: UNSAFE, may block.
530 then shoveString 0 xs
531 else constructErrorAndFail "writeChunks"
533 shoveString (n + 1) xs
535 shoveString initPos s
536 #else /* ndef __HUGS__ */
537 #ifndef __PARALLEL_HASKELL__
538 writeBlocks :: ForeignObj -> Addr -> Int -> Int -> String -> IO ()
540 writeBlocks :: Addr -> Addr -> Int -> Int -> String -> IO ()
542 writeBlocks obj buf (I# bufLen) (I# initPos#) s =
544 write_char :: Addr -> Int# -> Char# -> IO ()
545 write_char (A# buf#) n# c# =
547 case (writeCharOffAddr# buf# n# c# s#) of s2# -> (# s2#, () #)
549 shoveString :: Int# -> [Char] -> IO ()
554 At the end of a buffer write, update the buffer position
555 in the underlying file object, so that if the handle
556 is subsequently dropped by the program, the whole
557 buffer will be properly flushed.
559 There's one case where this delayed up-date of the buffer
560 position can go wrong: if a thread is killed, it might be
561 in the middle of filling up a buffer, with the result that
562 the partial buffer update is lost upon finalisation. However,
563 by the time killThread is supported, Haskell finalisers are also
564 likely to be in, which means the 'IOFileObject' hack can go
568 setBufWPtr obj (I# n)
574 rc <- mayBlock obj (writeFileObject obj (I# (n +# 1#))) -- ConcHask: UNSAFE, may block.
576 then shoveString 0# xs
577 else constructErrorAndFail "writeChunks"
579 shoveString (n +# 1#) xs
581 shoveString initPos# s
582 #endif /* ndef __HUGS__ */
584 #ifndef __PARALLEL_HASKELL__
585 writeChars :: ForeignObj -> String -> IO ()
587 writeChars :: Addr -> String -> IO ()
589 writeChars _fo "" = return ()
590 writeChars fo (c:cs) = do
591 rc <- mayBlock fo (filePutc fo c) -- ConcHask: UNSAFE, may block.
593 then writeChars fo cs
594 else constructErrorAndFail "writeChars"
598 Computation @hPrint hdl t@ writes the string representation of {\em t}
599 given by the @shows@ function to the file or channel managed by {\em
602 [ Seem to have disappeared from the 1.4 interface - SOF 2/97 ]
605 hPrint :: Show a => Handle -> a -> IO ()
606 hPrint hdl = hPutStrLn hdl . show
609 Derived action @hPutStrLn hdl str@ writes the string \tr{str} to
610 the handle \tr{hdl}, adding a newline at the end.
613 hPutStrLn :: Handle -> String -> IO ()
614 hPutStrLn hndl str = do
621 %*********************************************************
623 \subsection{Try and bracket}
625 %*********************************************************
627 The construct @try comp@ exposes errors which occur within a
628 computation, and which are not fully handled. It always succeeds.
631 try :: IO a -> IO (Either IOError a)
632 try f = catch (do r <- f
636 bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c
637 bracket before after m = do
645 -- variant of the above where middle computation doesn't want x
646 bracket_ :: IO a -> (a -> IO b) -> IO c -> IO c
647 bracket_ before after m = do
656 %*********************************************************
658 \subsection{Standard IO}
660 %*********************************************************
662 The Prelude has from Day 1 provided a collection of common
663 IO functions. We define these here, but let the Prelude
667 putChar :: Char -> IO ()
668 putChar c = hPutChar stdout c
670 putStr :: String -> IO ()
671 putStr s = hPutStr stdout s
673 putStrLn :: String -> IO ()
674 putStrLn s = do putStr s
677 print :: Show a => a -> IO ()
678 print x = putStrLn (show x)
681 getChar = hGetChar stdin
684 getLine = hGetLine stdin
686 getContents :: IO String
687 getContents = hGetContents stdin
689 interact :: (String -> String) -> IO ()
690 interact f = do s <- getContents
693 readFile :: FilePath -> IO String
694 readFile name = openFile name ReadMode >>= hGetContents
696 writeFile :: FilePath -> String -> IO ()
697 writeFile name str = do
698 hdl <- openFile name WriteMode
702 appendFile :: FilePath -> String -> IO ()
703 appendFile name str = do
704 hdl <- openFile name AppendMode
708 readLn :: Read a => IO a
709 readLn = do l <- getLine
723 unimp s = error ("IO library: function not implemented: " ++ s)
725 type FILE_STAR = Addr
730 = Handle { name :: FilePath,
731 file :: FILE_STAR, -- C handle
732 mut :: IORef Handle_Mut, -- open/closed/semiclosed
738 = Handle_Mut { state :: HState
742 set_state :: Handle -> HState -> IO ()
743 set_state hdl new_state
744 = writeIORef (mut hdl) (Handle_Mut { state = new_state })
745 get_state :: Handle -> IO HState
747 = readIORef (mut hdl) >>= \m -> return (state m)
749 mkErr :: Handle -> String -> IO a
751 = do mut <- readIORef (mut h)
752 when (state mut /= HClosed)
753 (nh_close (file h) >> set_state h HClosed)
755 ioError (IOError msg)
760 file = unsafePerformIO nh_stdin,
761 mut = unsafePerformIO (newIORef (Handle_Mut { state = HOpen })),
768 file = unsafePerformIO nh_stdout,
769 mut = unsafePerformIO (newIORef (Handle_Mut { state = HOpen })),
776 file = unsafePerformIO nh_stderr,
777 mut = unsafePerformIO (newIORef (Handle_Mut { state = HOpen })),
782 instance Eq Handle where
783 h1 == h2 = file h1 == file h2
785 instance Show Handle where
786 showsPrec _ h = showString ("`" ++ name h ++ "'")
793 data IOMode = ReadMode | WriteMode | AppendMode | ReadWriteMode
794 deriving (Eq, Ord, Ix, Bounded, Enum, Read, Show)
796 data BufferMode = NoBuffering | LineBuffering
797 | BlockBuffering (Maybe Int)
798 deriving (Eq, Ord, Read, Show)
800 data SeekMode = AbsoluteSeek | RelativeSeek | SeekFromEnd
801 deriving (Eq, Ord, Ix, Bounded, Enum, Read, Show)
803 data HState = HOpen | HSemiClosed | HClosed
807 -- A global variable holding a list of all open handles.
808 -- Each handle is present as many times as it has been opened.
809 -- Any given file is allowed to have _either_ one writeable handle
810 -- or many readable handles in this list. The list is used to
811 -- enforce single-writer multiple reader semantics. It also
812 -- provides a list of handles for System.exitWith to flush and
813 -- close. In order not to have to put all this stuff in the
814 -- Prelude, System.exitWith merely runs prelExitWithAction,
815 -- which is originally Nothing, but which we set to Just ...
816 -- once handles appear in the list.
818 allHandles :: IORef [Handle]
819 allHandles = unsafePerformIO (newIORef [])
821 elemWriterHandles :: FilePath -> IO Bool
822 elemAllHandles :: FilePath -> IO Bool
823 addHandle :: Handle -> IO ()
824 delHandle :: Handle -> IO ()
825 cleanupHandles :: IO ()
828 = do hdls <- readIORef allHandles
829 mapM_ cleanupHandle hdls
834 >> nh_errno >>= \_ -> return ()
836 = nh_flush (file h) >> nh_close (file h)
837 >> nh_errno >>= \_ -> return ()
839 elemWriterHandles fname
840 = do hdls <- readIORef allHandles
841 let hdls_w = filter ((/= ReadMode).mode) hdls
842 return (fname `elem` (map name hdls_w))
845 = do hdls <- readIORef allHandles
846 return (fname `elem` (map name hdls))
849 = do cleanup_action <- readIORef prelCleanupAfterRunAction
850 case cleanup_action of
852 -> writeIORef prelCleanupAfterRunAction (Just cleanupHandles)
855 hdls <- readIORef allHandles
856 writeIORef allHandles (hdl : hdls)
859 = do hdls <- readIORef allHandles
860 let hdls' = takeWhile (/= hdl) hdls
861 ++ drop 1 (dropWhile (/= hdl) hdls)
862 writeIORef allHandles hdls'
866 openFile :: FilePath -> IOMode -> IO Handle
870 = (ioError.IOError) "openFile: empty file name"
873 = do not_ok <- elemWriterHandles f
875 then (ioError.IOError)
876 ("openFile: `" ++ f ++ "' in " ++ show mode
877 ++ ": is already open for writing")
878 else openFile_main f mode
881 = do not_ok <- elemAllHandles f
883 then (ioError.IOError)
884 ("openFile: `" ++ f ++ "' in " ++ show mode
885 ++ ": is already open for reading or writing")
886 else openFile_main f mode
889 = openFile_main f mode
892 = copy_String_to_cstring f >>= \nameptr ->
893 nh_open nameptr (mode2num mode) >>= \fh ->
896 then (ioError.IOError)
897 ("openFile: can't open <<" ++ f ++ ">> in " ++ show mode)
898 else do r <- newIORef (Handle_Mut { state = HOpen })
899 let hdl = Handle { name = f, file = fh,
900 mut = r, mode = mode }
904 mode2num :: IOMode -> Int
905 mode2num ReadMode = 0
906 mode2num WriteMode = 1
907 mode2num AppendMode = 2
908 mode2num ReadWriteMode
910 ("openFile <<" ++ f ++ ">>: ReadWriteMode not supported")
912 hClose :: Handle -> IO ()
914 = do mut <- readIORef (mut h)
915 if state mut == HClosed
917 ("hClose on closed handle " ++ show h)
919 do set_state h HClosed
926 ("hClose: error closing " ++ name h)
928 hGetContents :: Handle -> IO String
931 = mkErr h ("hGetContents on non-ReadMode handle " ++ show h)
933 = do mut <- readIORef (mut h)
934 if state mut /= HOpen
936 ("hGetContents on closed/semiclosed handle " ++ show h)
938 do set_state h HSemiClosed
942 = nh_read f >>= \ci ->
945 else read_all f >>= \rest ->
946 return ((primIntToChar ci):rest)
948 hPutStr :: Handle -> String -> IO ()
951 = mkErr h ("hPutStr on ReadMode handle " ++ show h)
953 = do mut <- readIORef (mut h)
954 if state mut /= HOpen
956 ("hPutStr on closed/semiclosed handle " ++ show h)
957 else write_all (file h) s
962 = nh_write f c >> write_all f cs
964 hFileSize :: Handle -> IO Integer
966 = do sz <- nh_filesize (file h)
969 then return (fromIntegral sz)
970 else mkErr h ("hFileSize on " ++ show h)
972 hIsEOF :: Handle -> IO Bool
974 = do iseof <- nh_iseof (file h)
977 then return (iseof /= 0)
978 else mkErr h ("hIsEOF on " ++ show h)
983 hSetBuffering :: Handle -> BufferMode -> IO ()
984 hSetBuffering = unimp "IO.hSetBuffering"
985 hGetBuffering :: Handle -> IO BufferMode
986 hGetBuffering = unimp "IO.hGetBuffering"
988 hFlush :: Handle -> IO ()
990 = do mut <- readIORef (mut h)
991 if state mut /= HOpen
993 ("hFlush on closed/semiclosed file " ++ name h)
994 else nh_flush (file h)
996 hGetPosn :: Handle -> IO HandlePosn
997 hGetPosn = unimp "IO.hGetPosn"
998 hSetPosn :: HandlePosn -> IO ()
999 hSetPosn = unimp "IO.hSetPosn"
1000 hSeek :: Handle -> SeekMode -> Integer -> IO ()
1001 hSeek = unimp "IO.hSeek"
1002 hWaitForInput :: Handle -> Int -> IO Bool
1003 hWaitForInput = unimp "hWaitForInput"
1004 hReady :: Handle -> IO Bool
1005 hReady h = unimp "hReady" -- hWaitForInput h 0
1007 hGetChar :: Handle -> IO Char
1009 = nh_read (file h) >>= \ci ->
1010 return (primIntToChar ci)
1012 hGetLine :: Handle -> IO String
1013 hGetLine h = do c <- hGetChar h
1014 if c=='\n' then return ""
1015 else do cs <- hGetLine h
1018 hLookAhead :: Handle -> IO Char
1019 hLookAhead = unimp "IO.hLookAhead"
1022 hPutChar :: Handle -> Char -> IO ()
1023 hPutChar h c = hPutStr h [c]
1025 hPutStrLn :: Handle -> String -> IO ()
1026 hPutStrLn h s = do { hPutStr h s; hPutChar h '\n' }
1028 hPrint :: Show a => Handle -> a -> IO ()
1029 hPrint h = hPutStrLn h . show
1031 hIsOpen, hIsClosed, hIsReadable, hIsWritable :: Handle -> IO Bool
1032 hIsOpen h = do { s <- get_state h; return (s == HOpen) }
1033 hIsClosed h = do { s <- get_state h; return (s == HClosed) }
1034 hIsReadable h = return (mode h == ReadMode)
1035 hIsWritable h = return (mode h `elem` [WriteMode, AppendMode])
1037 hIsSeekable :: Handle -> IO Bool
1038 hIsSeekable = unimp "IO.hIsSeekable"
1041 isAlreadyExistsError,
1042 isDoesNotExistError,
1043 isAlreadyInUseError,
1047 isUserError :: IOError -> Bool
1049 isIllegalOperation = unimp "IO.isIllegalOperation"
1050 isAlreadyExistsError = unimp "IO.isAlreadyExistsError"
1051 isDoesNotExistError = unimp "IO.isDoesNotExistError"
1052 isAlreadyInUseError = unimp "IO.isAlreadyInUseError"
1053 isFullError = unimp "IO.isFullError"
1054 isEOFError = unimp "IO.isEOFError"
1055 isPermissionError = unimp "IO.isPermissionError"
1056 isUserError = unimp "IO.isUserError"
1059 ioeGetErrorString :: IOError -> String
1060 ioeGetErrorString = unimp "IO.ioeGetErrorString"
1061 ioeGetHandle :: IOError -> Maybe Handle
1062 ioeGetHandle = unimp "IO.ioeGetHandle"
1063 ioeGetFileName :: IOError -> Maybe FilePath
1064 ioeGetFileName = unimp "IO.ioeGetFileName"
1066 try :: IO a -> IO (Either IOError a)
1067 try p = catch (p >>= (return . Right)) (return . Left)
1069 bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c
1070 bracket before after m = do
1078 -- variant of the above where middle computation doesn't want x
1079 bracket_ :: IO a -> (a -> IO b) -> IO c -> IO c
1080 bracket_ before after m = do
1088 -- TODO: Hugs/slurpFile
1089 slurpFile = unimp "IO.slurpFile"
1092 #endif /* #ifndef __HUGS__ */