2 % (c) The AQUA Project, Glasgow University, 1994-1998
4 \section[IO]{Module @IO@}
6 Implementation of the standard Haskell IO interface, see
7 @http://haskell.org/onlinelibrary/io.html@ for the official
11 {-# OPTIONS -fno-implicit-prelude -#include "cbits/stgio.h" #-}
14 Handle, -- abstract, instance of: Eq, Show.
15 HandlePosn(..), -- abstract, instance of: Eq, Show.
17 IOMode(ReadMode,WriteMode,AppendMode,ReadWriteMode),
18 BufferMode(NoBuffering,LineBuffering,BlockBuffering),
19 SeekMode(AbsoluteSeek,RelativeSeek,SeekFromEnd),
21 stdin, stdout, stderr, -- :: Handle
23 openFile, -- :: FilePath -> IOMode -> IO Handle
24 hClose, -- :: Handle -> IO ()
25 hFileSize, -- :: Handle -> IO Integer
26 hIsEOF, -- :: Handle -> IO Bool
29 hSetBuffering, -- :: Handle -> BufferMode -> IO ()
30 hGetBuffering, -- :: Handle -> IO BufferMode
31 hFlush, -- :: Handle -> IO ()
32 hGetPosn, -- :: Handle -> IO HandlePosn
33 hSetPosn, -- :: Handle -> HandlePosn -> IO ()
34 hSeek, -- :: Handle -> SeekMode -> Integer -> IO ()
35 hWaitForInput, -- :: Handle -> Int -> IO Bool
36 hReady, -- :: Handle -> IO Bool
37 hGetChar, -- :: Handle -> IO Char
38 hGetLine, -- :: Handle -> IO [Char]
39 hLookAhead, -- :: Handle -> IO Char
40 hGetContents, -- :: Handle -> IO [Char]
41 hPutChar, -- :: Handle -> Char -> IO ()
42 hPutStr, -- :: Handle -> [Char] -> IO ()
43 hPutStrLn, -- :: Handle -> [Char] -> IO ()
44 hPrint, -- :: Show a => Handle -> a -> IO ()
45 hIsOpen, hIsClosed, -- :: Handle -> IO Bool
46 hIsReadable, hIsWritable, -- :: Handle -> IO Bool
47 hIsSeekable, -- :: Handle -> IO Bool
49 isAlreadyExistsError, isDoesNotExistError, -- :: IOError -> Bool
50 isAlreadyInUseError, isFullError,
51 isEOFError, isIllegalOperation,
52 isPermissionError, isUserError,
54 ioeGetErrorString, -- :: IOError -> String
55 ioeGetHandle, -- :: IOError -> Maybe Handle
56 ioeGetFileName, -- :: IOError -> Maybe FilePath
58 try, -- :: IO a -> IO (Either IOError a)
59 bracket, -- :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c
60 bracket_, -- :: IO a -> (a -> IO b) -> IO c -> IO c
62 -- Non-standard extension (but will hopefully become standard with 1.5) is
63 -- to export the Prelude io functions via IO (in addition to exporting them
64 -- from the prelude...for now.)
66 FilePath, -- :: String
68 ioError, -- :: IOError -> IO a
69 userError, -- :: String -> IOError
70 catch, -- :: IO a -> (IOError -> IO a) -> IO a
71 interact, -- :: (String -> String) -> IO ()
73 putChar, -- :: Char -> IO ()
74 putStr, -- :: String -> IO ()
75 putStrLn, -- :: String -> IO ()
76 print, -- :: Show a => a -> IO ()
77 getChar, -- :: IO Char
78 getLine, -- :: IO String
79 getContents, -- :: IO String
80 readFile, -- :: FilePath -> IO String
81 writeFile, -- :: FilePath -> String -> IO ()
82 appendFile, -- :: FilePath -> String -> IO ()
83 readIO, -- :: Read a => String -> IO a
84 readLn, -- :: Read a => IO a
102 import PrelHandle -- much of the real stuff is in here
104 import PrelRead ( readParen, Read(..), reads, lex,
108 import PrelMaybe ( Either(..), Maybe(..) )
109 import PrelAddr ( Addr(..), nullAddr )
110 import PrelArr ( ByteArray )
111 import PrelPack ( unpackNBytesAccST )
112 import PrelException ( ioError, catch )
114 #ifndef __PARALLEL_HASKELL__
115 import PrelForeign ( ForeignObj )
118 import Char ( ord, chr )
120 #endif /* ndef __HUGS__ */
125 Standard instances for @Handle@:
128 instance Eq IOError where
129 (IOError h1 e1 loc1 str1) == (IOError h2 e2 loc2 str2) =
130 e1==e2 && str1==str2 && h1==h2 && loc1 == loc2
132 instance Eq Handle where
133 (Handle h1) == (Handle h2) = h1 == h2
135 --Type declared in IOHandle, instance here because it depends on Eq.Handle
136 instance Eq HandlePosn where
137 (HandlePosn h1 p1) == (HandlePosn h2 p2) = p1==p2 && h1==h2
139 -- Type declared in IOBase, instance here because it
140 -- depends on PrelRead.(Read Maybe) instance.
141 instance Read BufferMode where
144 (\r -> let lr = lex r
146 [(NoBuffering, rest) | ("NoBuffering", rest) <- lr] ++
147 [(LineBuffering,rest) | ("LineBuffering",rest) <- lr] ++
148 [(BlockBuffering mb,rest2) | ("BlockBuffering",rest1) <- lr,
149 (mb, rest2) <- reads rest1])
153 %*********************************************************
155 \subsection{Simple input operations}
157 %*********************************************************
159 Computation @hReady hdl@ indicates whether at least
160 one item is available for input from handle {\em hdl}.
162 @hWaitForInput@ is the generalisation, wait for \tr{n} milliseconds
163 before deciding whether the Handle has run dry or not.
165 If @hWaitForInput@ finds anything in the Handle's buffer, it immediately returns.
166 If not, it tries to read from the underlying OS handle. Notice that
167 for buffered Handles connected to terminals this means waiting until a complete
171 hReady :: Handle -> IO Bool
172 hReady h = hWaitForInput h 0
174 hWaitForInput :: Handle -> Int -> IO Bool
175 hWaitForInput handle msecs =
176 wantReadableHandle "hWaitForInput" handle $ \ handle_ -> do
177 rc <- inputReady (haFO__ handle_) (msecs::Int) -- ConcHask: SAFE, won't block
181 _ -> constructErrorAndFail "hWaitForInput"
184 @hGetChar hdl@ reads the next character from handle @hdl@,
185 blocking until a character is available.
188 hGetChar :: Handle -> IO Char
190 wantReadableHandle "hGetChar" handle $ \ handle_ -> do
191 let fo = haFO__ handle_
192 intc <- mayBlock fo (fileGetc fo) -- ConcHask: UNSAFE, may block
193 if intc /= ((-1)::Int)
194 then return (chr intc)
195 else constructErrorAndFail "hGetChar"
198 If EOF is reached before EOL is encountered, ignore the
199 EOF and return the partial line. Next attempt at calling
200 hGetLine on the handle will yield an EOF IO exception though.
202 hGetLine :: Handle -> IO String
216 if isEOFError err then
228 @hLookahead hdl@ returns the next character from handle @hdl@
229 without removing it from the input buffer, blocking until a
230 character is available.
233 hLookAhead :: Handle -> IO Char
235 wantReadableHandle "hLookAhead" handle $ \ handle_ -> do
236 let fo = haFO__ handle_
237 intc <- mayBlock fo (fileLookAhead fo) -- ConcHask: UNSAFE, may block
239 then return (chr intc)
240 else constructErrorAndFail "hLookAhead"
245 %*********************************************************
247 \subsection{Getting the entire contents of a handle}
249 %*********************************************************
251 @hGetContents hdl@ returns the list of characters corresponding
252 to the unread portion of the channel or file managed by @hdl@,
253 which is made semi-closed.
256 hGetContents :: Handle -> IO String
257 hGetContents handle =
258 -- can't use wantReadableHandle here, because we want to side effect
260 withHandle handle $ \ handle_ -> do
261 case haType__ handle_ of
262 ErrorHandle theError -> ioError theError
263 ClosedHandle -> ioe_closedHandle "hGetContents" handle
264 SemiClosedHandle -> ioe_closedHandle "hGetContents" handle
265 AppendHandle -> ioError not_readable_error
266 WriteHandle -> ioError not_readable_error
269 To avoid introducing an extra layer of buffering here,
270 we provide three lazy read methods, based on character,
271 line, and block buffering.
273 let handle_' = handle_{ haType__ = SemiClosedHandle }
274 case (haBufferMode__ handle_) of
276 str <- unsafeInterleaveIO (lazyReadLine handle (haFO__ handle_))
277 return (handle_', str)
278 BlockBuffering _ -> do
279 str <- unsafeInterleaveIO (lazyReadBlock handle (haFO__ handle_))
280 return (handle_', str)
282 str <- unsafeInterleaveIO (lazyReadChar handle (haFO__ handle_))
283 return (handle_', str)
286 IOError (Just handle) IllegalOperation "hGetContents"
287 ("handle is not open for reading")
290 Note that someone may close the semi-closed handle (or change its buffering),
291 so each these lazy read functions are pulled on, they have to check whether
292 the handle has indeed been closed.
295 #ifndef __PARALLEL_HASKELL__
296 lazyReadBlock :: Handle -> ForeignObj -> IO String
297 lazyReadLine :: Handle -> ForeignObj -> IO String
298 lazyReadChar :: Handle -> ForeignObj -> IO String
300 lazyReadBlock :: Handle -> Addr -> IO String
301 lazyReadLine :: Handle -> Addr -> IO String
302 lazyReadChar :: Handle -> Addr -> IO String
305 lazyReadBlock handle fo = do
306 buf <- getBufStart fo 0
307 bytes <- mayBlock fo (readBlock fo) -- ConcHask: UNSAFE, may block.
309 -3 -> -- buffering has been turned off, use lazyReadChar instead
310 lazyReadChar handle fo
312 -1 -> -- an error occurred, close the handle
313 withHandle handle $ \ handle_ -> do
314 closeFile (haFO__ handle_) 0{-don't bother flushing-} -- ConcHask: SAFE, won't block.
315 return (handle_ { haType__ = ClosedHandle,
316 haFO__ = nullFile__ },
319 more <- unsafeInterleaveIO (lazyReadBlock handle fo)
320 stToIO (unpackNBytesAccST buf bytes more)
322 lazyReadLine handle fo = do
323 bytes <- mayBlock fo (readLine fo) -- ConcHask: UNSAFE, may block.
325 -3 -> -- buffering has been turned off, use lazyReadChar instead
326 lazyReadChar handle fo
327 -2 -> return "" -- handle closed by someone else, stop reading.
328 -1 -> -- an error occurred, close the handle
329 withHandle handle $ \ handle_ -> do
330 closeFile (haFO__ handle_) 0{- don't bother flushing-} -- ConcHask: SAFE, won't block
331 return (handle_ { haType__ = ClosedHandle,
332 haFO__ = nullFile__ },
335 more <- unsafeInterleaveIO (lazyReadLine handle fo)
336 buf <- getBufStart fo bytes -- ConcHask: won't block
337 stToIO (unpackNBytesAccST buf bytes more)
339 lazyReadChar handle fo = do
340 char <- mayBlock fo (readChar fo) -- ConcHask: UNSAFE, may block.
342 -4 -> -- buffering is now block-buffered, use lazyReadBlock instead
343 lazyReadBlock handle fo
345 -3 -> -- buffering is now line-buffered, use lazyReadLine instead
346 lazyReadLine handle fo
348 -1 -> -- error, silently close handle.
349 withHandle handle $ \ handle_ -> do
350 closeFile (haFO__ handle_) 0{-don't bother flusing-} -- ConcHask: SAFE, won't block
351 return (handle_{ haType__ = ClosedHandle,
352 haFO__ = nullFile__ },
355 more <- unsafeInterleaveIO (lazyReadChar handle fo)
356 return (chr char : more)
361 %*********************************************************
363 \subsection{Simple output functions}
365 %*********************************************************
367 @hPutChar hdl ch@ writes the character @ch@ to the file
368 or channel managed by @hdl@. Characters may be buffered if
369 buffering is enabled for @hdl@
372 hPutChar :: Handle -> Char -> IO ()
374 wantWriteableHandle "hPutChar" handle $ \ handle_ -> do
375 let fo = haFO__ handle_
377 rc <- mayBlock fo (filePutc fo c) -- ConcHask: UNSAFE, may block.
380 else constructErrorAndFail "hPutChar"
384 @hPutStr hdl s@ writes the string @s@ to the file or
385 channel managed by @hdl@, buffering the output if needs be.
388 hPutStr :: Handle -> String -> IO ()
390 wantWriteableHandle "hPutStr" handle $ \ handle_ -> do
391 let fo = haFO__ handle_
393 case haBufferMode__ handle_ of
395 buf <- getWriteableBuf fo
398 writeLines fo buf bsz pos str
399 BlockBuffering _ -> do
400 buf <- getWriteableBuf fo
403 writeBlocks fo buf bsz pos str
408 Going across the border between Haskell and C is relatively costly,
409 so for block writes we pack the character strings on the Haskell-side
410 before passing the external write routine a pointer to the buffer.
415 #ifdef __CONCURRENT_HASKELL__
416 /* See comment in shoveString below for explanation */
417 #warning delayed update of buffer disnae work with killThread
420 #ifndef __PARALLEL_HASKELL__
421 writeLines :: ForeignObj -> Addr -> Int -> Int -> String -> IO ()
423 writeLines :: Addr -> Addr -> Int -> Int -> String -> IO ()
425 writeLines obj buf bufLen initPos s =
427 shoveString :: Int -> [Char] -> IO ()
432 At the end of a buffer write, update the buffer position
433 in the underlying file object, so that if the handle
434 is subsequently dropped by the program, the whole
435 buffer will be properly flushed.
437 There's one case where this delayed up-date of the buffer
438 position can go wrong: if a thread is killed, it might be
439 in the middle of filling up a buffer, with the result that
440 the partial buffer update is lost upon finalisation. Not
441 that killing of threads is supported at the moment.
447 primWriteCharOffAddr buf n x
448 {- Flushing on buffer exhaustion or newlines (even if it isn't the last one) -}
449 if n == bufLen || x == '\n'
451 rc <- mayBlock obj (writeFileObject obj (n + 1)) -- ConcHask: UNSAFE, may block.
453 then shoveString 0 xs
454 else constructErrorAndFail "writeLines"
456 shoveString (n + 1) xs
458 shoveString initPos s
459 #else /* ndef __HUGS__ */
460 #ifndef __PARALLEL_HASKELL__
461 writeLines :: ForeignObj -> Addr -> Int -> Int -> String -> IO ()
463 writeLines :: Addr -> Addr -> Int -> Int -> String -> IO ()
465 writeLines obj buf (I# bufLen) (I# initPos#) s =
467 write_char :: Addr -> Int# -> Char# -> IO ()
468 write_char (A# buf#) n# c# =
470 case (writeCharOffAddr# buf# n# c# s#) of s2# -> (# s2#, () #)
472 shoveString :: Int# -> [Char] -> IO ()
477 At the end of a buffer write, update the buffer position
478 in the underlying file object, so that if the handle
479 is subsequently dropped by the program, the whole
480 buffer will be properly flushed.
482 There's one case where this delayed up-date of the buffer
483 position can go wrong: if a thread is killed, it might be
484 in the middle of filling up a buffer, with the result that
485 the partial buffer update is lost upon finalisation. Not
486 that killing of threads is supported at the moment.
489 setBufWPtr obj (I# n)
493 {- Flushing on buffer exhaustion or newlines (even if it isn't the last one) -}
494 if n ==# bufLen || x `eqChar#` '\n'#
496 rc <- mayBlock obj (writeFileObject obj (I# (n +# 1#))) -- ConcHask: UNSAFE, may block.
498 then shoveString 0# xs
499 else constructErrorAndFail "writeLines"
501 shoveString (n +# 1#) xs
503 shoveString initPos# s
504 #endif /* ndef __HUGS__ */
507 #ifndef __PARALLEL_HASKELL__
508 writeBlocks :: ForeignObj -> Addr -> Int -> Int -> String -> IO ()
510 writeBlocks :: Addr -> Addr -> Int -> Int -> String -> IO ()
512 writeBlocks obj buf bufLen initPos s =
514 shoveString :: Int -> [Char] -> IO ()
519 At the end of a buffer write, update the buffer position
520 in the underlying file object, so that if the handle
521 is subsequently dropped by the program, the whole
522 buffer will be properly flushed.
524 There's one case where this delayed up-date of the buffer
525 position can go wrong: if a thread is killed, it might be
526 in the middle of filling up a buffer, with the result that
527 the partial buffer update is lost upon finalisation. However,
528 by the time killThread is supported, Haskell finalisers are also
529 likely to be in, which means the 'IOFileObject' hack can go
536 primWriteCharOffAddr buf n x
539 rc <- mayBlock obj (writeFileObject obj (n + 1)) -- ConcHask: UNSAFE, may block.
541 then shoveString 0 xs
542 else constructErrorAndFail "writeChunks"
544 shoveString (n + 1) xs
546 shoveString initPos s
547 #else /* ndef __HUGS__ */
548 #ifndef __PARALLEL_HASKELL__
549 writeBlocks :: ForeignObj -> Addr -> Int -> Int -> String -> IO ()
551 writeBlocks :: Addr -> Addr -> Int -> Int -> String -> IO ()
553 writeBlocks obj buf (I# bufLen) (I# initPos#) s =
555 write_char :: Addr -> Int# -> Char# -> IO ()
556 write_char (A# buf#) n# c# =
558 case (writeCharOffAddr# buf# n# c# s#) of s2# -> (# s2#, () #)
560 shoveString :: Int# -> [Char] -> IO ()
565 At the end of a buffer write, update the buffer position
566 in the underlying file object, so that if the handle
567 is subsequently dropped by the program, the whole
568 buffer will be properly flushed.
570 There's one case where this delayed up-date of the buffer
571 position can go wrong: if a thread is killed, it might be
572 in the middle of filling up a buffer, with the result that
573 the partial buffer update is lost upon finalisation. However,
574 by the time killThread is supported, Haskell finalisers are also
575 likely to be in, which means the 'IOFileObject' hack can go
579 setBufWPtr obj (I# n)
585 rc <- mayBlock obj (writeFileObject obj (I# (n +# 1#))) -- ConcHask: UNSAFE, may block.
587 then shoveString 0# xs
588 else constructErrorAndFail "writeChunks"
590 shoveString (n +# 1#) xs
592 shoveString initPos# s
593 #endif /* ndef __HUGS__ */
595 #ifndef __PARALLEL_HASKELL__
596 writeChars :: ForeignObj -> String -> IO ()
598 writeChars :: Addr -> String -> IO ()
600 writeChars _fo "" = return ()
601 writeChars fo (c:cs) = do
602 rc <- mayBlock fo (filePutc fo c) -- ConcHask: UNSAFE, may block.
604 then writeChars fo cs
605 else constructErrorAndFail "writeChars"
609 Computation @hPrint hdl t@ writes the string representation of {\em t}
610 given by the @shows@ function to the file or channel managed by {\em
613 [ Seem to have disappeared from the 1.4 interface - SOF 2/97 ]
616 hPrint :: Show a => Handle -> a -> IO ()
617 hPrint hdl = hPutStrLn hdl . show
620 Derived action @hPutStrLn hdl str@ writes the string \tr{str} to
621 the handle \tr{hdl}, adding a newline at the end.
624 hPutStrLn :: Handle -> String -> IO ()
625 hPutStrLn hndl str = do
632 %*********************************************************
634 \subsection{Try and bracket}
636 %*********************************************************
638 The construct @try comp@ exposes errors which occur within a
639 computation, and which are not fully handled. It always succeeds.
642 try :: IO a -> IO (Either IOError a)
643 try f = catch (do r <- f
647 bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c
648 bracket before after m = do
656 -- variant of the above where middle computation doesn't want x
657 bracket_ :: IO a -> (a -> IO b) -> IO c -> IO c
658 bracket_ before after m = do
667 %*********************************************************
669 \subsection{Standard IO}
671 %*********************************************************
673 The Prelude has from Day 1 provided a collection of common
674 IO functions. We define these here, but let the Prelude
678 putChar :: Char -> IO ()
679 putChar c = hPutChar stdout c
681 putStr :: String -> IO ()
682 putStr s = hPutStr stdout s
684 putStrLn :: String -> IO ()
685 putStrLn s = do putStr s
688 print :: Show a => a -> IO ()
689 print x = putStrLn (show x)
692 getChar = hGetChar stdin
695 getLine = hGetLine stdin
697 getContents :: IO String
698 getContents = hGetContents stdin
700 interact :: (String -> String) -> IO ()
701 interact f = do s <- getContents
704 readFile :: FilePath -> IO String
705 readFile name = openFile name ReadMode >>= hGetContents
707 writeFile :: FilePath -> String -> IO ()
708 writeFile name str = do
709 hdl <- openFile name WriteMode
713 appendFile :: FilePath -> String -> IO ()
714 appendFile name str = do
715 hdl <- openFile name AppendMode
719 readLn :: Read a => IO a
720 readLn = do l <- getLine
733 unimp s = error ("IO library: function not implemented: " ++ s)
735 type FILE_STAR = Addr
740 = Handle { name :: FilePath,
741 file :: FILE_STAR, -- C handle
742 mut :: IORef Handle_Mut, -- open/closed/semiclosed
748 = Handle_Mut { state :: HState
751 set_state :: Handle -> HState -> IO ()
752 set_state hdl new_state
753 = writeIORef (mut hdl) (Handle_Mut { state = new_state })
754 get_state :: Handle -> IO HState
756 = readIORef (mut hdl) >>= \m -> return (state m)
758 mkErr :: Handle -> String -> IO a
760 = do nh_close (file h)
762 ioError (IOError msg)
767 file = primRunST nh_stdin,
768 mut = primRunST (newIORef (Handle_Mut { state = HOpen })),
775 file = primRunST nh_stdout,
776 mut = primRunST (newIORef (Handle_Mut { state = HOpen })),
783 file = primRunST nh_stderr,
784 mut = primRunST (newIORef (Handle_Mut { state = HOpen })),
789 instance Eq Handle where
790 h1 == h2 = file h1 == file h2
792 instance Show Handle where
793 showsPrec _ h = showString ("<<" ++ name h ++ ">>")
800 data IOMode = ReadMode | WriteMode | AppendMode | ReadWriteMode
801 deriving (Eq, Ord, Ix, Bounded, Enum, Read, Show)
803 data BufferMode = NoBuffering | LineBuffering
805 deriving (Eq, Ord, Read, Show)
807 data SeekMode = AbsoluteSeek | RelativeSeek | SeekFromEnd
808 deriving (Eq, Ord, Ix, Bounded, Enum, Read, Show)
810 data HState = HOpen | HSemiClosed | HClosed
813 openFile :: FilePath -> IOMode -> IO Handle
815 = copy_String_to_cstring f >>= \nameptr ->
816 nh_open nameptr (mode2num mode) >>= \fh ->
819 then (ioError.IOError)
820 ("openFile: can't open <<" ++ f ++ ">> in " ++ show mode)
821 else do r <- newIORef (Handle_Mut { state = HOpen })
829 mode2num :: IOMode -> Int
830 mode2num ReadMode = 0
831 mode2num WriteMode = 1
832 mode2num AppendMode = 2
833 mode2num ReadWriteMode
835 ("openFile <<" ++ f ++ ">>: ReadWriteMode not supported")
837 hClose :: Handle -> IO ()
839 = do mut <- readIORef (mut h)
840 if state mut == HClosed
842 ("hClose on closed handle " ++ show h)
844 do set_state h HClosed
850 ("hClose: error closing " ++ name h)
852 hGetContents :: Handle -> IO String
855 = mkErr h ("hGetContents on non-ReadMode handle " ++ show h)
857 = do mut <- readIORef (mut h)
858 if state mut /= HOpen
860 ("hGetContents on closed/semiclosed handle " ++ show h)
862 do set_state h HSemiClosed
866 = nh_read f >>= \ci ->
869 else read_all f >>= \rest ->
870 return ((primIntToChar ci):rest)
872 hPutStr :: Handle -> String -> IO ()
875 = mkErr h ("hPutStr on ReadMode handle " ++ show h)
877 = do mut <- readIORef (mut h)
878 if state mut /= HOpen
880 ("hPutStr on closed/semiclosed handle " ++ show h)
881 else write_all (file h) s
886 = nh_write f c >> write_all f cs
888 hFileSize :: Handle -> IO Integer
890 = do sz <- nh_filesize (file h)
893 then return (fromIntegral sz)
894 else mkErr h ("hFileSize on " ++ show h)
896 hIsEOF :: Handle -> IO Bool
898 = do iseof <- nh_iseof (file h)
901 then return (iseof /= 0)
902 else mkErr h ("hIsEOF on " ++ show h)
907 hSetBuffering :: Handle -> BufferMode -> IO ()
908 hSetBuffering = unimp "IO.hSetBuffering"
909 hGetBuffering :: Handle -> IO BufferMode
910 hGetBuffering = unimp "IO.hGetBuffering"
912 hFlush :: Handle -> IO ()
914 = do mut <- readIORef (mut h)
915 if state mut /= HOpen
917 ("hFlush on closed/semiclosed file " ++ name h)
918 else nh_flush (file h)
920 hGetPosn :: Handle -> IO HandlePosn
921 hGetPosn = unimp "IO.hGetPosn"
922 hSetPosn :: HandlePosn -> IO ()
923 hSetPosn = unimp "IO.hSetPosn"
924 hSeek :: Handle -> SeekMode -> Integer -> IO ()
925 hSeek = unimp "IO.hSeek"
926 hWaitForInput :: Handle -> Int -> IO Bool
927 hWaitForInput = unimp "hWaitForInput"
928 hReady :: Handle -> IO Bool
929 hReady h = unimp "hReady" -- hWaitForInput h 0
931 hGetChar :: Handle -> IO Char
933 = nh_read (file h) >>= \ci ->
934 return (primIntToChar ci)
936 hGetLine :: Handle -> IO String
937 hGetLine h = do c <- hGetChar h
938 if c=='\n' then return ""
939 else do cs <- hGetLine h
942 hLookAhead :: Handle -> IO Char
943 hLookAhead = unimp "IO.hLookAhead"
946 hPutChar :: Handle -> Char -> IO ()
947 hPutChar h c = hPutStr h [c]
949 hPutStrLn :: Handle -> String -> IO ()
950 hPutStrLn h s = do { hPutStr h s; hPutChar h '\n' }
952 hPrint :: Show a => Handle -> a -> IO ()
953 hPrint h = hPutStrLn h . show
955 hIsOpen, hIsClosed, hIsReadable, hIsWritable :: Handle -> IO Bool
956 hIsOpen h = do { s <- get_state h; return (s == HOpen) }
957 hIsClosed h = do { s <- get_state h; return (s == HClosed) }
958 hIsReadable h = return (mode h == ReadMode)
959 hIsWritable h = return (mode h `elem` [WriteMode, AppendMode])
961 hIsSeekable :: Handle -> IO Bool
962 hIsSeekable = unimp "IO.hIsSeekable"
965 isAlreadyExistsError,
971 isUserError :: IOError -> Bool
973 isIllegalOperation = unimp "IO.isIllegalOperation"
974 isAlreadyExistsError = unimp "IO.isAlreadyExistsError"
975 isDoesNotExistError = unimp "IO.isDoesNotExistError"
976 isAlreadyInUseError = unimp "IO.isAlreadyInUseError"
977 isFullError = unimp "IO.isFullError"
978 isEOFError = unimp "IO.isEOFError"
979 isPermissionError = unimp "IO.isPermissionError"
980 isUserError = unimp "IO.isUserError"
983 ioeGetErrorString :: IOError -> String
984 ioeGetErrorString = unimp "IO.ioeGetErrorString"
985 ioeGetHandle :: IOError -> Maybe Handle
986 ioeGetHandle = unimp "IO.ioeGetHandle"
987 ioeGetFileName :: IOError -> Maybe FilePath
988 ioeGetFileName = unimp "IO.ioeGetFileName"
990 try :: IO a -> IO (Either IOError a)
991 try p = catch (p >>= (return . Right)) (return . Left)
993 bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c
994 bracket before after m = do
1002 -- variant of the above where middle computation doesn't want x
1003 bracket_ :: IO a -> (a -> IO b) -> IO c -> IO c
1004 bracket_ before after m = do
1011 -- TODO: Hugs/slurpFile
1012 slurpFile = unimp "IO.slurpFile"
1015 #endif /* #ifndef __HUGS__ */