2 % (c) The AQUA Project, Glasgow University, 1994-1996
5 \section[IO]{Module @IO@}
8 {-# OPTIONS -fno-implicit-prelude -#include "cbits/stgio.h" #-}
13 IOMode(ReadMode,WriteMode,AppendMode,ReadWriteMode),
14 BufferMode(NoBuffering,LineBuffering,BlockBuffering),
15 SeekMode(AbsoluteSeek,RelativeSeek,SeekFromEnd),
17 stdin, stdout, stderr,
20 hFileSize, hIsEOF, isEOF,
21 hSetBuffering, hGetBuffering, hFlush,
22 hGetPosn, hSetPosn, hSeek,
23 hWaitForInput, hReady, hGetChar, hGetLine, hLookAhead, hGetContents,
24 hPutChar, hPutStr, hPutStrLn, hPrint,
25 hIsOpen, hIsClosed, hIsReadable, hIsWritable, hIsSeekable,
27 isAlreadyExistsError, isDoesNotExistError, isAlreadyInUseError,
28 isFullError, isEOFError,
29 isIllegalOperation, isPermissionError, isUserError,
31 ioeGetHandle, ioeGetFileName,
32 try, bracket, bracket_
38 import ArrBase ( MutableByteArray(..), newCharArray )
39 import IOHandle -- much of the real stuff is in here
40 import PackedString ( nilPS, packCBytesST, unpackPS )
43 import Foreign ( ForeignObj, Addr, makeForeignObj, writeForeignObj )
44 import Char ( ord, chr )
47 %*********************************************************
49 \subsection{Signatures}
51 %*********************************************************
54 --IOHandle:hClose :: Handle -> IO ()
55 --IOHandle:hFileSize :: Handle -> IO Integer
56 --IOHandle:hFlush :: Handle -> IO ()
57 --IOHandle:hGetBuffering :: Handle -> IO BufferMode
58 hGetChar :: Handle -> IO Char
59 hGetContents :: Handle -> IO String
60 --IOHandle:hGetPosn :: Handle -> IO HandlePosn
61 --IOHandle:hIsClosed :: Handle -> IO Bool
62 --IOHandle:hIsEOF :: Handle -> IO Bool
63 --IOHandle:hIsOpen :: Handle -> IO Bool
64 --IOHandle:hIsReadable :: Handle -> IO Bool
65 --IOHandle:hIsSeekable :: Handle -> IO Bool
66 --IOHandle:hIsWritable :: Handle -> IO Bool
67 hLookAhead :: Handle -> IO Char
68 hPrint :: Show a => Handle -> a -> IO ()
69 hPutChar :: Handle -> Char -> IO ()
70 hPutStr :: Handle -> String -> IO ()
71 hPutStrLn :: Handle -> String -> IO ()
72 hReady :: Handle -> IO Bool
73 hWaitForInput :: Handle -> Int -> IO Bool
75 --IOHandle:hSeek :: Handle -> SeekMode -> Integer -> IO ()
76 --IOHandle:hSetBuffering :: Handle -> BufferMode -> IO ()
77 --IOHandle:hSetPosn :: HandlePosn -> IO ()
78 -- ioeGetFileName :: IOError -> Maybe FilePath
79 -- ioeGetErrorString :: IOError -> Maybe String
80 -- ioeGetHandle :: IOError -> Maybe Handle
81 -- isAlreadyExistsError :: IOError -> Bool
82 -- isAlreadyInUseError :: IOError -> Bool
83 --IOHandle:isEOF :: IO Bool
84 -- isEOFError :: IOError -> Bool
85 -- isFullError :: IOError -> Bool
86 -- isIllegalOperation :: IOError -> Bool
87 -- isPermissionError :: IOError -> Bool
88 -- isUserError :: IOError -> Maybe String
89 --IOHandle:openFile :: FilePath -> IOMode -> IO Handle
90 --IOHandle:stdin, stdout, stderr :: Handle
93 Standard instances for @Handle@:
96 instance Eq IOError where
97 (IOError h1 e1 str1) == (IOError h2 e2 str2) =
98 e1==e2 && str1==str2 && h1==h2
100 instance Eq Handle where
102 unsafePerformPrimIO (
103 ioToPrimIO (readHandle h1) >>= \ h1_ ->
104 ioToPrimIO (writeHandle h1 h1_) >>
105 ioToPrimIO (readHandle h2) >>= \ h2_ ->
106 ioToPrimIO (writeHandle h2 h2_) >>
109 (ErrorHandle (IOError h1 _ _), ErrorHandle (IOError h2 _ _)) -> h1 == h2
110 (ClosedHandle, ClosedHandle) -> True
111 (SemiClosedHandle v1 _, SemiClosedHandle v2 _) -> v1 == v2
112 (ReadHandle v1 _ _ , ReadHandle v2 _ _) -> v1 == v2
113 (WriteHandle v1 _ _ , WriteHandle v2 _ _) -> v1 == v2
114 (AppendHandle v1 _ _ , AppendHandle v2 _ _) -> v1 == v2
115 (ReadWriteHandle v1 _ _ , ReadWriteHandle v2 _ _) -> v1 == v2
118 instance Show Handle where {showsPrec p h = showString "<<Handle>>"}
122 %*********************************************************
124 \subsection{Simple input operations}
126 %*********************************************************
128 Computation @hReady hdl@ indicates whether at least
129 one item is available for input from handle {\em hdl}.
131 @hWaitForInput@ is the generalisation, wait for \tr{n} seconds
132 before deciding whether the Handle has run dry or not.
135 --hReady :: Handle -> IO Bool
136 hReady h = hWaitForInput h 0
138 --hWaitForInput :: Handle -> Int -> IO Bool
139 hWaitForInput handle nsecs =
140 readHandle handle >>= \ htype ->
142 ErrorHandle ioError ->
143 writeHandle handle htype >>
146 writeHandle handle htype >>
147 ioe_closedHandle handle
148 SemiClosedHandle _ _ ->
149 writeHandle handle htype >>
150 ioe_closedHandle handle
151 AppendHandle _ _ _ ->
152 writeHandle handle htype >>
153 fail (IOError (Just handle) IllegalOperation "handle is not open for reading")
155 writeHandle handle htype >>
156 fail (IOError (Just handle) IllegalOperation "handle is not open for reading")
158 _ccall_ inputReady (filePtr other) nsecs `thenIO_Prim` \ rc ->
159 writeHandle handle (markHandle htype) >>
163 _ -> constructErrorAndFail "hWaitForInput"
166 Computation $hGetChar hdl$ reads the next character from handle
167 {\em hdl}, blocking until a character is available.
170 --hGetChar :: Handle -> IO Char
173 readHandle handle >>= \ htype ->
175 ErrorHandle ioError ->
176 writeHandle handle htype >>
179 writeHandle handle htype >>
180 ioe_closedHandle handle
181 SemiClosedHandle _ _ ->
182 writeHandle handle htype >>
183 ioe_closedHandle handle
184 AppendHandle _ _ _ ->
185 writeHandle handle htype >>
186 fail (IOError (Just handle) IllegalOperation "handle is not open for reading")
188 writeHandle handle htype >>
189 fail (IOError (Just handle) IllegalOperation "handle is not open for reading")
191 _ccall_ fileGetc (filePtr other) `thenIO_Prim` \ intc ->
192 writeHandle handle (markHandle htype) >>
193 if intc /= ``EOF'' then
196 constructErrorAndFail "hGetChar"
198 hGetLine :: Handle -> IO String
200 hGetChar h >>= \ c ->
204 hGetLine h >>= \ s -> return (c:s)
207 Computation $hLookahead hdl$ returns the next character from handle
208 {\em hdl} without removing it from the input buffer, blocking until a
209 character is available.
212 --hLookAhead :: Handle -> IO Char
215 readHandle handle >>= \ htype ->
217 ErrorHandle ioError ->
218 writeHandle handle htype >>
221 writeHandle handle htype >>
222 ioe_closedHandle handle
223 SemiClosedHandle _ _ ->
224 writeHandle handle htype >>
225 ioe_closedHandle handle
226 AppendHandle _ _ _ ->
227 writeHandle handle htype >>
228 fail (IOError (Just handle) IllegalOperation "handle is not open for reading")
230 writeHandle handle htype >>
231 fail (IOError (Just handle) IllegalOperation "handle is not open for reading")
233 _ccall_ fileLookAhead (filePtr other) `thenIO_Prim` \ intc ->
234 writeHandle handle (markHandle htype) >>
235 if intc /= ``EOF'' then
238 constructErrorAndFail "hLookAhead"
242 %*********************************************************
244 \subsection{Getting the entire contents of a handle}
246 %*********************************************************
248 Computation $hGetContents hdl$ returns the list of characters
249 corresponding to the unread portion of the channel or file managed by
250 {\em hdl}, which is made semi-closed.
253 --hGetContents :: Handle -> IO String
255 hGetContents handle =
256 readHandle handle >>= \ htype ->
258 ErrorHandle ioError ->
259 writeHandle handle htype >>
262 writeHandle handle htype >>
263 ioe_closedHandle handle
264 SemiClosedHandle _ _ ->
265 writeHandle handle htype >>
266 ioe_closedHandle handle
267 AppendHandle _ _ _ ->
268 writeHandle handle htype >>
269 fail (IOError (Just handle) IllegalOperation "handle is not open for reading")
271 writeHandle handle htype >>
272 fail (IOError (Just handle) IllegalOperation "handle is not open for reading")
275 To avoid introducing an extra layer of buffering here,
276 we provide three lazy read methods, based on character,
277 line, and block buffering.
279 stToIO (getBufferMode other) >>= \ other ->
280 case (bufferMode other) of
281 Just LineBuffering ->
282 allocBuf Nothing >>= \ buf_info ->
283 writeHandle handle (SemiClosedHandle (filePtr other) buf_info)
285 unsafeInterleavePrimIO (lazyReadLine handle)
286 `thenIO_Prim` \ contents ->
289 Just (BlockBuffering size) ->
290 allocBuf size >>= \ buf_info ->
291 writeHandle handle (SemiClosedHandle (filePtr other) buf_info)
293 unsafeInterleavePrimIO (lazyReadBlock handle)
294 `thenIO_Prim` \ contents ->
296 _ -> -- Nothing is treated pessimistically as NoBuffering
297 writeHandle handle (SemiClosedHandle (filePtr other) (``NULL'', 0))
299 unsafeInterleavePrimIO (lazyReadChar handle)
300 `thenIO_Prim` \ contents ->
303 allocBuf :: Maybe Int -> IO (Addr, Int)
305 _ccall_ malloc size `thenIO_Prim` \ buf ->
306 if buf /= ``NULL'' then
309 fail (IOError Nothing ResourceExhausted "not enough virtual memory")
314 Nothing -> ``BUFSIZ''
317 Note that someone may yank our handle out from under us, and then re-use
318 the same FILE * for something else. Therefore, we have to re-examine the
319 handle every time through.
322 lazyReadBlock :: Handle -> PrimIO String
323 lazyReadLine :: Handle -> PrimIO String
324 lazyReadChar :: Handle -> PrimIO String
326 lazyReadBlock handle =
327 ioToST (readHandle handle) >>= \ htype ->
329 -- There cannae be an ErrorHandle here
331 ioToST (writeHandle handle htype) >>
333 SemiClosedHandle fp (buf, size) ->
334 _ccall_ readBlock buf fp size >>= \ bytes ->
337 else packCBytesST bytes buf) >>= \ some ->
339 _ccall_ free buf >>= \ () ->
340 _ccall_ closeFile fp >>
342 writeForeignObj fp ``NULL'' >>
343 ioToST (writeHandle handle (SemiClosedHandle fp (``NULL'', 0))) >>
345 ioToST (writeHandle handle (SemiClosedHandle ``NULL'' (``NULL'', 0))) >>
347 returnPrimIO (unpackPS some)
349 ioToST (writeHandle handle htype) >>
350 unsafeInterleavePrimIO (lazyReadBlock handle)
352 returnPrimIO (unpackPS some ++ more)
354 lazyReadLine handle =
355 ioToST (readHandle handle) >>= \ htype ->
357 -- There cannae be an ErrorHandle here
359 ioToST (writeHandle handle htype) >>
361 SemiClosedHandle fp (buf, size) ->
362 _ccall_ readLine buf fp size >>= \ bytes ->
365 else packCBytesST bytes buf) >>= \ some ->
367 _ccall_ free buf >>= \ () ->
368 _ccall_ closeFile fp >>
370 writeForeignObj fp ``NULL'' >>
371 ioToST (writeHandle handle (SemiClosedHandle fp (``NULL'', 0))) >>
373 ioToST (writeHandle handle (SemiClosedHandle ``NULL'' (``NULL'', 0))) >>
375 returnPrimIO (unpackPS some)
377 ioToST (writeHandle handle htype) >>
378 unsafeInterleavePrimIO (lazyReadLine handle)
380 returnPrimIO (unpackPS some ++ more)
382 lazyReadChar handle =
383 ioToST (readHandle handle) >>= \ htype ->
385 -- There cannae be an ErrorHandle here
387 ioToST (writeHandle handle htype) >>
389 SemiClosedHandle fp buf_info ->
390 _ccall_ readChar fp >>= \ char ->
391 if char == ``EOF'' then
392 _ccall_ closeFile fp >>
394 writeForeignObj fp ``NULL'' >>
395 ioToST (writeHandle handle (SemiClosedHandle fp (``NULL'', 0))) >>
397 ioToST (writeHandle handle (SemiClosedHandle ``NULL'' (``NULL'', 0))) >>
401 ioToST (writeHandle handle htype) >>
402 unsafeInterleavePrimIO (lazyReadChar handle)
404 returnPrimIO (chr char : more)
409 %*********************************************************
411 \subsection{Simple output functions}
413 %*********************************************************
415 Computation $hPutChar hdl c$ writes the character {\em c} to the file
416 or channel managed by {\em hdl}. Characters may be buffered if
417 buffering is enabled for {\em hdl}.
420 --hPutChar :: Handle -> Char -> IO ()
423 readHandle handle >>= \ htype ->
425 ErrorHandle ioError ->
426 writeHandle handle htype >>
429 writeHandle handle htype >>
430 ioe_closedHandle handle
431 SemiClosedHandle _ _ ->
432 writeHandle handle htype >>
433 ioe_closedHandle handle
435 writeHandle handle htype >>
436 fail (IOError (Just handle) IllegalOperation "handle is not open for writing")
438 _ccall_ filePutc (filePtr other) (ord c) `thenIO_Prim` \ rc ->
439 writeHandle handle (markHandle htype) >>
443 constructErrorAndFail "hPutChar"
446 Computation $hPutStr hdl s$ writes the string {\em s} to the file or
447 channel managed by {\em hdl}.
450 --hPutStr :: Handle -> String -> IO ()
453 readHandle handle >>= \ htype ->
455 ErrorHandle ioError ->
456 writeHandle handle htype >>
459 writeHandle handle htype >>
460 ioe_closedHandle handle
461 SemiClosedHandle _ _ ->
462 writeHandle handle htype >>
463 ioe_closedHandle handle
465 writeHandle handle htype >>
466 fail (IOError (Just handle) IllegalOperation "handle is not open for writing")
469 The code below is not correct for line-buffered terminal streams,
470 as the output stream is not flushed when terminal input is requested
471 again, just upon seeing a newline character. A temporary fix for the
472 most common line-buffered output stream, stdout, is to assume the
473 buffering it was given when created (no buffering). This is not
474 as bad as it looks, since stdio buffering sits underneath this.
478 getBufferMode other `thenIO_Prim` \ other ->
479 (case bufferMode other of
480 Just LineBuffering ->
481 writeChars (filePtr other) str
482 --writeLines (filePtr other) str
483 Just (BlockBuffering (Just size)) ->
484 writeBlocks (filePtr other) size str
485 Just (BlockBuffering Nothing) ->
486 writeBlocks (filePtr other) ``BUFSIZ'' str
487 _ -> -- Nothing is treated pessimistically as NoBuffering
488 writeChars (filePtr other) str
489 ) `thenIO_Prim` \ success ->
490 writeHandle handle (markHandle other) >>
494 constructErrorAndFail "hPutStr"
497 writeLines :: ForeignObj -> String -> PrimIO Bool
499 writeLines :: Addr -> String -> PrimIO Bool
501 writeLines = writeChunks ``BUFSIZ'' True
504 writeBlocks :: ForeignObj -> Int -> String -> PrimIO Bool
506 writeBlocks :: Addr -> Int -> String -> PrimIO Bool
508 writeBlocks fp size s = writeChunks size False fp s
511 The breaking up of output into lines along \n boundaries
512 works fine as long as there are newlines to split by.
513 Avoid the splitting up into lines alltogether (doesn't work
514 for overly long lines like the stuff that showsPrec instances
515 normally return). Instead, we split them up into fixed size
516 chunks before blasting them off to the Real World.
518 Hacked to avoid multiple passes over the strings - unsightly, but
519 a whole lot quicker. -- SOF 3/96
523 writeChunks :: Int -> Bool -> ForeignObj -> String -> PrimIO Bool
525 writeChunks :: Int -> Bool -> Addr -> String -> PrimIO Bool
527 writeChunks (I# bufLen) chopOnNewLine fp s =
528 newCharArray (0,I# bufLen) >>= \ arr@(MutableByteArray _ arr#) ->
530 write_char :: MutableByteArray# RealWorld -> Int# -> Char# -> PrimIO ()
531 write_char arr# n x = ST $ \ (S# s#) ->
532 case (writeCharArray# arr# n x s#) of { s1# ->
535 shoveString :: Int# -> [Char] -> PrimIO Bool
542 _ccall_ writeFile arr fp (I# n) >>= \rc ->
546 write_char arr# n x >>
548 {- Flushing lines - should we bother? Yes, for line-buffered output. -}
549 if n ==# bufLen || (chopOnNewLine && (x `eqChar#` '\n'#)) then
550 _ccall_ writeFile arr fp (I# (n +# 1#)) >>= \ rc ->
556 shoveString (n +# 1#) xs
561 writeChars :: ForeignObj -> String -> PrimIO Bool
563 writeChars :: Addr -> String -> PrimIO Bool
565 writeChars fp "" = returnPrimIO True
566 writeChars fp (c:cs) =
567 _ccall_ filePutc fp (ord c) >>= \ rc ->
574 Computation $hPrint hdl t$ writes the string representation of {\em t}
575 given by the $shows$ function to the file or channel managed by {\em
578 SOF 2/97: Seem to have disappeared in 1.4 libs.
581 --hPrint :: Show a => Handle -> a -> IO ()
582 hPrint hdl = hPutStr hdl . show
585 Derived action @hPutStrLn hdl str@ writes the string \tr{str} to
586 the handle \tr{hdl}, adding a newline at the end.
589 --hPutStrLn :: Handle -> String -> IO ()
590 hPutStrLn hndl str = do
597 %*********************************************************
599 \subsection{Try and bracket}
601 %*********************************************************
603 The construct $try comp$ exposes errors which occur within a
604 computation, and which are not fully handled. It always succeeds.
607 try :: IO a -> IO (Either IOError a)
608 try f = catch (do r <- f
612 bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c
613 bracket before after m = do
621 -- variant of the above where middle computation doesn't want x
622 bracket_ :: IO a -> (a -> IO b) -> IO c -> IO c
623 bracket_ before after m = do