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