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 )
46 %*********************************************************
48 \subsection{Signatures}
50 %*********************************************************
53 --IOHandle:hClose :: Handle -> IO ()
54 --IOHandle:hFileSize :: Handle -> IO Integer
55 --IOHandle:hFlush :: Handle -> IO ()
56 --IOHandle:hGetBuffering :: Handle -> IO BufferMode
57 hGetChar :: Handle -> IO Char
58 hGetContents :: Handle -> IO String
59 --IOHandle:hGetPosn :: Handle -> IO HandlePosn
60 --IOHandle:hIsClosed :: Handle -> IO Bool
61 --IOHandle:hIsEOF :: Handle -> IO Bool
62 --IOHandle:hIsOpen :: Handle -> IO Bool
63 --IOHandle:hIsReadable :: Handle -> IO Bool
64 --IOHandle:hIsSeekable :: Handle -> IO Bool
65 --IOHandle:hIsWritable :: Handle -> IO Bool
66 hLookAhead :: Handle -> IO Char
67 hPrint :: Show a => Handle -> a -> IO ()
68 hPutChar :: Handle -> Char -> IO ()
69 hPutStr :: Handle -> String -> IO ()
70 hPutStrLn :: Handle -> String -> IO ()
71 hReady :: Handle -> IO Bool
72 hWaitForInput :: Handle -> Int -> IO Bool
74 --IOHandle:hSeek :: Handle -> SeekMode -> Integer -> IO ()
75 --IOHandle:hSetBuffering :: Handle -> BufferMode -> IO ()
76 --IOHandle:hSetPosn :: HandlePosn -> IO ()
77 -- ioeGetFileName :: IOError -> Maybe FilePath
78 -- ioeGetErrorString :: IOError -> Maybe String
79 -- ioeGetHandle :: IOError -> Maybe Handle
80 -- isAlreadyExistsError :: IOError -> Bool
81 -- isAlreadyInUseError :: IOError -> Bool
82 --IOHandle:isEOF :: IO Bool
83 -- isEOFError :: IOError -> Bool
84 -- isFullError :: IOError -> Bool
85 -- isIllegalOperation :: IOError -> Bool
86 -- isPermissionError :: IOError -> Bool
87 -- isUserError :: IOError -> Maybe String
88 --IOHandle:openFile :: FilePath -> IOMode -> IO Handle
89 --IOHandle:stdin, stdout, stderr :: Handle
92 Standard instances for @Handle@:
95 instance Eq IOError where
96 (IOError h1 e1 str1) == (IOError h2 e2 str2) =
97 e1==e2 && str1==str2 && h1==h2
99 instance Eq Handle where
101 unsafePerformPrimIO (
102 ioToPrimIO (readHandle h1) >>= \ h1_ ->
103 ioToPrimIO (writeHandle h1 h1_) >>
104 ioToPrimIO (readHandle h2) >>= \ h2_ ->
105 ioToPrimIO (writeHandle h2 h2_) >>
108 (ErrorHandle (IOError h1 _ _), ErrorHandle (IOError h2 _ _)) -> h1 == h2
109 (ClosedHandle, ClosedHandle) -> True
110 (SemiClosedHandle v1 _, SemiClosedHandle v2 _) -> v1 == v2
111 (ReadHandle v1 _ _ , ReadHandle v2 _ _) -> v1 == v2
112 (WriteHandle v1 _ _ , WriteHandle v2 _ _) -> v1 == v2
113 (AppendHandle v1 _ _ , AppendHandle v2 _ _) -> v1 == v2
114 (ReadWriteHandle v1 _ _ , ReadWriteHandle v2 _ _) -> v1 == v2
117 instance Show Handle where {showsPrec p h = showString "<<Handle>>"}
121 %*********************************************************
123 \subsection{Simple input operations}
125 %*********************************************************
127 Computation @hReady hdl@ indicates whether at least
128 one item is available for input from handle {\em hdl}.
130 @hWaitForInput@ is the generalisation, wait for \tr{n} seconds
131 before deciding whether the Handle has run dry or not.
134 --hReady :: Handle -> IO Bool
135 hReady h = hWaitForInput h 0
137 --hWaitForInput :: Handle -> Int -> IO Bool
138 hWaitForInput handle nsecs =
139 readHandle handle >>= \ htype ->
141 ErrorHandle ioError ->
142 writeHandle handle htype >>
145 writeHandle handle htype >>
146 ioe_closedHandle handle
147 SemiClosedHandle _ _ ->
148 writeHandle handle htype >>
149 ioe_closedHandle handle
150 AppendHandle _ _ _ ->
151 writeHandle handle htype >>
152 fail (IOError (Just handle) IllegalOperation "handle is not open for reading")
154 writeHandle handle htype >>
155 fail (IOError (Just handle) IllegalOperation "handle is not open for reading")
157 _ccall_ inputReady (filePtr other) nsecs `thenIO_Prim` \ rc ->
158 writeHandle handle (markHandle htype) >>
162 _ -> constructErrorAndFail "hWaitForInput"
165 Computation $hGetChar hdl$ reads the next character from handle
166 {\em hdl}, blocking until a character is available.
169 --hGetChar :: Handle -> IO Char
172 readHandle handle >>= \ htype ->
174 ErrorHandle ioError ->
175 writeHandle handle htype >>
178 writeHandle handle htype >>
179 ioe_closedHandle handle
180 SemiClosedHandle _ _ ->
181 writeHandle handle htype >>
182 ioe_closedHandle handle
183 AppendHandle _ _ _ ->
184 writeHandle handle htype >>
185 fail (IOError (Just handle) IllegalOperation "handle is not open for reading")
187 writeHandle handle htype >>
188 fail (IOError (Just handle) IllegalOperation "handle is not open for reading")
190 _ccall_ fileGetc (filePtr other) `thenIO_Prim` \ intc ->
191 writeHandle handle (markHandle htype) >>
192 if intc /= ``EOF'' then
195 constructErrorAndFail "hGetChar"
197 hGetLine :: Handle -> IO String
199 hGetChar h >>= \ c ->
203 hGetLine h >>= \ s -> return (c:s)
206 Computation $hLookahead hdl$ returns the next character from handle
207 {\em hdl} without removing it from the input buffer, blocking until a
208 character is available.
211 --hLookAhead :: Handle -> IO Char
214 readHandle handle >>= \ htype ->
216 ErrorHandle ioError ->
217 writeHandle handle htype >>
220 writeHandle handle htype >>
221 ioe_closedHandle handle
222 SemiClosedHandle _ _ ->
223 writeHandle handle htype >>
224 ioe_closedHandle handle
225 AppendHandle _ _ _ ->
226 writeHandle handle htype >>
227 fail (IOError (Just handle) IllegalOperation "handle is not open for reading")
229 writeHandle handle htype >>
230 fail (IOError (Just handle) IllegalOperation "handle is not open for reading")
232 _ccall_ fileLookAhead (filePtr other) `thenIO_Prim` \ intc ->
233 writeHandle handle (markHandle htype) >>
234 if intc /= ``EOF'' then
237 constructErrorAndFail "hLookAhead"
241 %*********************************************************
243 \subsection{Getting the entire contents of a handle}
245 %*********************************************************
247 Computation $hGetContents hdl$ returns the list of characters
248 corresponding to the unread portion of the channel or file managed by
249 {\em hdl}, which is made semi-closed.
252 --hGetContents :: Handle -> IO String
254 hGetContents handle =
255 readHandle handle >>= \ htype ->
257 ErrorHandle ioError ->
258 writeHandle handle htype >>
261 writeHandle handle htype >>
262 ioe_closedHandle handle
263 SemiClosedHandle _ _ ->
264 writeHandle handle htype >>
265 ioe_closedHandle handle
266 AppendHandle _ _ _ ->
267 writeHandle handle htype >>
268 fail (IOError (Just handle) IllegalOperation "handle is not open for reading")
270 writeHandle handle htype >>
271 fail (IOError (Just handle) IllegalOperation "handle is not open for reading")
274 To avoid introducing an extra layer of buffering here,
275 we provide three lazy read methods, based on character,
276 line, and block buffering.
278 stToIO (getBufferMode other) >>= \ other ->
279 case (bufferMode other) of
280 Just LineBuffering ->
281 allocBuf Nothing >>= \ buf_info ->
282 writeHandle handle (SemiClosedHandle (filePtr other) buf_info)
284 unsafeInterleavePrimIO (lazyReadLine handle)
285 `thenIO_Prim` \ contents ->
288 Just (BlockBuffering size) ->
289 allocBuf size >>= \ buf_info ->
290 writeHandle handle (SemiClosedHandle (filePtr other) buf_info)
292 unsafeInterleavePrimIO (lazyReadBlock handle)
293 `thenIO_Prim` \ contents ->
295 _ -> -- Nothing is treated pessimistically as NoBuffering
296 writeHandle handle (SemiClosedHandle (filePtr other) (``NULL'', 0))
298 unsafeInterleavePrimIO (lazyReadChar handle)
299 `thenIO_Prim` \ contents ->
302 allocBuf :: Maybe Int -> IO (Addr, Int)
304 _ccall_ malloc size `thenIO_Prim` \ buf ->
305 if buf /= ``NULL'' then
308 fail (IOError Nothing ResourceExhausted "not enough virtual memory")
313 Nothing -> ``BUFSIZ''
316 Note that someone may yank our handle out from under us, and then re-use
317 the same FILE * for something else. Therefore, we have to re-examine the
318 handle every time through.
321 lazyReadBlock :: Handle -> PrimIO String
322 lazyReadLine :: Handle -> PrimIO String
323 lazyReadChar :: Handle -> PrimIO String
325 lazyReadBlock handle =
326 ioToST (readHandle handle) >>= \ htype ->
328 -- There cannae be an ErrorHandle here
330 ioToST (writeHandle handle htype) >>
332 SemiClosedHandle fp (buf, size) ->
333 _ccall_ readBlock buf fp size >>= \ bytes ->
336 else packCBytesST bytes buf) >>= \ some ->
338 _ccall_ free buf >>= \ () ->
339 _ccall_ closeFile fp >>
341 writeForeignObj fp ``NULL'' >>
342 ioToST (writeHandle handle (SemiClosedHandle fp (``NULL'', 0))) >>
344 ioToST (writeHandle handle (SemiClosedHandle ``NULL'' (``NULL'', 0))) >>
346 returnPrimIO (unpackPS some)
348 ioToST (writeHandle handle htype) >>
349 unsafeInterleavePrimIO (lazyReadBlock handle)
351 returnPrimIO (unpackPS some ++ more)
353 lazyReadLine handle =
354 ioToST (readHandle handle) >>= \ htype ->
356 -- There cannae be an ErrorHandle here
358 ioToST (writeHandle handle htype) >>
360 SemiClosedHandle fp (buf, size) ->
361 _ccall_ readLine buf fp size >>= \ bytes ->
364 else packCBytesST bytes buf) >>= \ some ->
366 _ccall_ free buf >>= \ () ->
367 _ccall_ closeFile fp >>
369 writeForeignObj fp ``NULL'' >>
370 ioToST (writeHandle handle (SemiClosedHandle fp (``NULL'', 0))) >>
372 ioToST (writeHandle handle (SemiClosedHandle ``NULL'' (``NULL'', 0))) >>
374 returnPrimIO (unpackPS some)
376 ioToST (writeHandle handle htype) >>
377 unsafeInterleavePrimIO (lazyReadLine handle)
379 returnPrimIO (unpackPS some ++ more)
381 lazyReadChar handle =
382 ioToST (readHandle handle) >>= \ htype ->
384 -- There cannae be an ErrorHandle here
386 ioToST (writeHandle handle htype) >>
388 SemiClosedHandle fp buf_info ->
389 _ccall_ readChar fp >>= \ char ->
390 if char == ``EOF'' then
391 _ccall_ closeFile fp >>
393 writeForeignObj fp ``NULL'' >>
394 ioToST (writeHandle handle (SemiClosedHandle fp (``NULL'', 0))) >>
396 ioToST (writeHandle handle (SemiClosedHandle ``NULL'' (``NULL'', 0))) >>
400 ioToST (writeHandle handle htype) >>
401 unsafeInterleavePrimIO (lazyReadChar handle)
403 returnPrimIO (chr char : more)
408 %*********************************************************
410 \subsection{Simple output functions}
412 %*********************************************************
414 Computation $hPutChar hdl c$ writes the character {\em c} to the file
415 or channel managed by {\em hdl}. Characters may be buffered if
416 buffering is enabled for {\em hdl}.
419 --hPutChar :: Handle -> Char -> IO ()
422 readHandle handle >>= \ htype ->
424 ErrorHandle ioError ->
425 writeHandle handle htype >>
428 writeHandle handle htype >>
429 ioe_closedHandle handle
430 SemiClosedHandle _ _ ->
431 writeHandle handle htype >>
432 ioe_closedHandle handle
434 writeHandle handle htype >>
435 fail (IOError (Just handle) IllegalOperation "handle is not open for writing")
437 _ccall_ filePutc (filePtr other) (ord c) `thenIO_Prim` \ rc ->
438 writeHandle handle (markHandle htype) >>
442 constructErrorAndFail "hPutChar"
445 Computation $hPutStr hdl s$ writes the string {\em s} to the file or
446 channel managed by {\em hdl}.
449 --hPutStr :: Handle -> String -> IO ()
452 readHandle handle >>= \ htype ->
454 ErrorHandle ioError ->
455 writeHandle handle htype >>
458 writeHandle handle htype >>
459 ioe_closedHandle handle
460 SemiClosedHandle _ _ ->
461 writeHandle handle htype >>
462 ioe_closedHandle handle
464 writeHandle handle htype >>
465 fail (IOError (Just handle) IllegalOperation "handle is not open for writing")
468 The code below is not correct for line-buffered terminal streams,
469 as the output stream is not flushed when terminal input is requested
470 again, just upon seeing a newline character. A temporary fix for the
471 most common line-buffered output stream, stdout, is to assume the
472 buffering it was given when created (no buffering). This is not
473 as bad as it looks, since stdio buffering sits underneath this.
477 getBufferMode other `thenIO_Prim` \ other ->
478 (case bufferMode other of
479 Just LineBuffering ->
480 writeChars (filePtr other) str
481 --writeLines (filePtr other) str
482 Just (BlockBuffering (Just size)) ->
483 writeBlocks (filePtr other) size str
484 Just (BlockBuffering Nothing) ->
485 writeBlocks (filePtr other) ``BUFSIZ'' str
486 _ -> -- Nothing is treated pessimistically as NoBuffering
487 writeChars (filePtr other) str
488 ) `thenIO_Prim` \ success ->
489 writeHandle handle (markHandle other) >>
493 constructErrorAndFail "hPutStr"
496 writeLines :: ForeignObj -> String -> PrimIO Bool
498 writeLines :: Addr -> String -> PrimIO Bool
500 writeLines = writeChunks ``BUFSIZ'' True
503 writeBlocks :: ForeignObj -> Int -> String -> PrimIO Bool
505 writeBlocks :: Addr -> Int -> String -> PrimIO Bool
507 writeBlocks fp size s = writeChunks size False fp s
510 The breaking up of output into lines along \n boundaries
511 works fine as long as there are newlines to split by.
512 Avoid the splitting up into lines alltogether (doesn't work
513 for overly long lines like the stuff that showsPrec instances
514 normally return). Instead, we split them up into fixed size
515 chunks before blasting them off to the Real World.
517 Hacked to avoid multiple passes over the strings - unsightly, but
518 a whole lot quicker. -- SOF 3/96
522 writeChunks :: Int -> Bool -> ForeignObj -> String -> PrimIO Bool
524 writeChunks :: Int -> Bool -> Addr -> String -> PrimIO Bool
526 writeChunks (I# bufLen) chopOnNewLine fp s =
527 newCharArray (0,I# bufLen) >>= \ arr@(MutableByteArray _ arr#) ->
529 write_char :: MutableByteArray# RealWorld -> Int# -> Char# -> PrimIO ()
530 write_char arr# n x = ST $ \ (S# s#) ->
531 case (writeCharArray# arr# n x s#) of { s1# ->
534 shoveString :: Int# -> [Char] -> PrimIO Bool
541 _ccall_ writeFile arr fp (I# n) >>= \rc ->
545 write_char arr# n x >>
547 {- Flushing lines - should we bother? Yes, for line-buffered output. -}
548 if n ==# bufLen || (chopOnNewLine && (x `eqChar#` '\n'#)) then
549 _ccall_ writeFile arr fp (I# (n +# 1#)) >>= \ rc ->
555 shoveString (n +# 1#) xs
560 writeChars :: ForeignObj -> String -> PrimIO Bool
562 writeChars :: Addr -> String -> PrimIO Bool
564 writeChars fp "" = returnPrimIO True
565 writeChars fp (c:cs) =
566 _ccall_ filePutc fp (ord c) >>= \ rc ->
573 Computation $hPrint hdl t$ writes the string representation of {\em t}
574 given by the $shows$ function to the file or channel managed by {\em
577 SOF 2/97: Seem to have disappeared in 1.4 libs.
580 --hPrint :: Show a => Handle -> a -> IO ()
581 hPrint hdl = hPutStr hdl . show
584 Derived action @hPutStrLn hdl str@ writes the string \tr{str} to
585 the handle \tr{hdl}, adding a newline at the end.
588 --hPutStrLn :: Handle -> String -> IO ()
589 hPutStrLn hndl str = do
596 %*********************************************************
598 \subsection{Try and bracket}
600 %*********************************************************
602 The construct $try comp$ exposes errors which occur within a
603 computation, and which are not fully handled. It always succeeds.
606 try :: IO a -> IO (Either IOError a)
607 try f = catch (do r <- f
611 bracket :: IO a -> (a -> IO b) -> (a -> IO c) -> IO c
612 bracket before after m = do
620 -- variant of the above where middle computation doesn't want x
621 bracket_ :: IO a -> (a -> IO b) -> IO c -> IO c
622 bracket_ before after m = do