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 hReady, hGetChar, 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
37 import ArrBase ( MutableByteArray(..), newCharArray )
38 import IOHandle -- much of the real stuff is in here
39 import PackedString ( nilPS, packCBytesST, unpackPS )
42 import Foreign ( makeForeignObj, writeForeignObj )
45 %*********************************************************
47 \subsection{Signatures}
49 %*********************************************************
52 --IOHandle:hClose :: Handle -> IO ()
53 --IOHandle:hFileSize :: Handle -> IO Integer
54 --IOHandle:hFlush :: Handle -> IO ()
55 --IOHandle:hGetBuffering :: Handle -> IO BufferMode
56 hGetChar :: Handle -> IO Char
57 hGetContents :: Handle -> IO String
58 --IOHandle:hGetPosn :: Handle -> IO HandlePosn
59 --IOHandle:hIsClosed :: Handle -> IO Bool
60 --IOHandle:hIsEOF :: Handle -> IO Bool
61 --IOHandle:hIsOpen :: Handle -> IO Bool
62 --IOHandle:hIsReadable :: Handle -> IO Bool
63 --IOHandle:hIsSeekable :: Handle -> IO Bool
64 --IOHandle:hIsWritable :: Handle -> IO Bool
65 hLookAhead :: Handle -> IO Char
66 hPrint :: Show a => Handle -> a -> IO ()
67 hPutChar :: Handle -> Char -> IO ()
68 hPutStr :: Handle -> String -> IO ()
69 hPutStrLn :: Handle -> String -> IO ()
70 hReady :: Handle -> IO Bool
71 --IOHandle:hSeek :: Handle -> SeekMode -> Integer -> IO ()
72 --IOHandle:hSetBuffering :: Handle -> BufferMode -> IO ()
73 --IOHandle:hSetPosn :: HandlePosn -> IO ()
74 -- ioeGetFileName :: IOError -> Maybe FilePath
75 -- ioeGetErrorString :: IOError -> Maybe String
76 -- ioeGetHandle :: IOError -> Maybe Handle
77 -- isAlreadyExistsError :: IOError -> Bool
78 -- isAlreadyInUseError :: IOError -> Bool
79 --IOHandle:isEOF :: IO Bool
80 -- isEOFError :: IOError -> Bool
81 -- isFullError :: IOError -> Bool
82 -- isIllegalOperation :: IOError -> Bool
83 -- isPermissionError :: IOError -> Bool
84 -- isUserError :: IOError -> Maybe String
85 --IOHandle:openFile :: FilePath -> IOMode -> IO Handle
86 --IOHandle:stdin, stdout, stderr :: Handle
89 %*********************************************************
91 \subsection{Simple input operations}
93 %*********************************************************
95 Computation $hReady hdl$ indicates whether at least
96 one item is available for input from handle {\em hdl}.
99 --hReady :: Handle -> IO Bool
101 readHandle handle >>= \ htype ->
103 ErrorHandle ioError ->
104 writeHandle handle htype >>
107 writeHandle handle htype >>
108 ioe_closedHandle handle
109 SemiClosedHandle _ _ ->
110 writeHandle handle htype >>
111 ioe_closedHandle handle
112 AppendHandle _ _ _ ->
113 writeHandle handle htype >>
114 fail (IOError (Just handle) IllegalOperation "handle is not open for reading")
116 writeHandle handle htype >>
117 fail (IOError (Just handle) IllegalOperation "handle is not open for reading")
119 _ccall_ inputReady (filePtr other) `thenIO_Prim` \ rc ->
120 writeHandle handle (markHandle htype) >>
124 _ -> constructErrorAndFail "hReady"
127 Computation $hGetChar hdl$ reads the next character from handle
128 {\em hdl}, blocking until a character is available.
131 --hGetChar :: Handle -> IO Char
134 readHandle handle >>= \ htype ->
136 ErrorHandle ioError ->
137 writeHandle handle htype >>
140 writeHandle handle htype >>
141 ioe_closedHandle handle
142 SemiClosedHandle _ _ ->
143 writeHandle handle htype >>
144 ioe_closedHandle handle
145 AppendHandle _ _ _ ->
146 writeHandle handle htype >>
147 fail (IOError (Just handle) IllegalOperation "handle is not open for reading")
149 writeHandle handle htype >>
150 fail (IOError (Just handle) IllegalOperation "handle is not open for reading")
152 _ccall_ fileGetc (filePtr other) `thenIO_Prim` \ intc ->
153 writeHandle handle (markHandle htype) >>
154 if intc /= ``EOF'' then
157 constructErrorAndFail "hGetChar"
160 Computation $hLookahead hdl$ returns the next character from handle
161 {\em hdl} without removing it from the input buffer, blocking until a
162 character is available.
165 --hLookAhead :: Handle -> IO Char
168 readHandle handle >>= \ htype ->
170 ErrorHandle ioError ->
171 writeHandle handle htype >>
174 writeHandle handle htype >>
175 ioe_closedHandle handle
176 SemiClosedHandle _ _ ->
177 writeHandle handle htype >>
178 ioe_closedHandle handle
179 AppendHandle _ _ _ ->
180 writeHandle handle htype >>
181 fail (IOError (Just handle) IllegalOperation "handle is not open for reading")
183 writeHandle handle htype >>
184 fail (IOError (Just handle) IllegalOperation "handle is not open for reading")
186 _ccall_ fileLookAhead (filePtr other) `thenIO_Prim` \ intc ->
187 writeHandle handle (markHandle htype) >>
188 if intc /= ``EOF'' then
191 constructErrorAndFail "hLookAhead"
195 %*********************************************************
197 \subsection{Getting the entire contents of a handle}
199 %*********************************************************
201 Computation $hGetContents hdl$ returns the list of characters
202 corresponding to the unread portion of the channel or file managed by
203 {\em hdl}, which is made semi-closed.
206 --hGetContents :: Handle -> IO String
208 hGetContents handle =
209 readHandle handle >>= \ htype ->
211 ErrorHandle ioError ->
212 writeHandle handle htype >>
215 writeHandle handle htype >>
216 ioe_closedHandle handle
217 SemiClosedHandle _ _ ->
218 writeHandle handle htype >>
219 ioe_closedHandle handle
220 AppendHandle _ _ _ ->
221 writeHandle handle htype >>
222 fail (IOError (Just handle) IllegalOperation "handle is not open for reading")
224 writeHandle handle htype >>
225 fail (IOError (Just handle) IllegalOperation "handle is not open for reading")
228 To avoid introducing an extra layer of buffering here,
229 we provide three lazy read methods, based on character,
230 line, and block buffering.
232 stToIO (getBufferMode other) >>= \ other ->
233 case (bufferMode other) of
234 Just LineBuffering ->
235 allocBuf Nothing >>= \ buf_info ->
236 writeHandle handle (SemiClosedHandle (filePtr other) buf_info)
238 unsafeInterleavePrimIO (lazyReadLine handle)
239 `thenIO_Prim` \ contents ->
242 Just (BlockBuffering size) ->
243 allocBuf size >>= \ buf_info ->
244 writeHandle handle (SemiClosedHandle (filePtr other) buf_info)
246 unsafeInterleavePrimIO (lazyReadBlock handle)
247 `thenIO_Prim` \ contents ->
249 _ -> -- Nothing is treated pessimistically as NoBuffering
250 writeHandle handle (SemiClosedHandle (filePtr other) (``NULL'', 0))
252 unsafeInterleavePrimIO (lazyReadChar handle)
253 `thenIO_Prim` \ contents ->
256 allocBuf :: Maybe Int -> IO (Addr, Int)
258 _ccall_ malloc size `thenIO_Prim` \ buf ->
259 if buf /= ``NULL'' then
262 fail (IOError Nothing ResourceExhausted "not enough virtual memory")
267 Nothing -> ``BUFSIZ''
270 Note that someone may yank our handle out from under us, and then re-use
271 the same FILE * for something else. Therefore, we have to re-examine the
272 handle every time through.
275 lazyReadBlock :: Handle -> PrimIO String
276 lazyReadLine :: Handle -> PrimIO String
277 lazyReadChar :: Handle -> PrimIO String
279 lazyReadBlock handle =
280 ioToST (readHandle handle) >>= \ htype ->
282 -- There cannae be an ErrorHandle here
284 ioToST (writeHandle handle htype) >>
286 SemiClosedHandle fp (buf, size) ->
287 _ccall_ readBlock buf fp size >>= \ bytes ->
290 else packCBytesST bytes buf) >>= \ some ->
292 _ccall_ free buf >>= \ () ->
293 _ccall_ closeFile fp >>
295 writeForeignObj fp ``NULL'' >>
296 ioToST (writeHandle handle (SemiClosedHandle fp (``NULL'', 0))) >>
298 ioToST (writeHandle handle (SemiClosedHandle ``NULL'' (``NULL'', 0))) >>
300 returnPrimIO (unpackPS some)
302 ioToST (writeHandle handle htype) >>
303 unsafeInterleavePrimIO (lazyReadBlock handle)
305 returnPrimIO (unpackPS some ++ more)
307 lazyReadLine handle =
308 ioToST (readHandle handle) >>= \ htype ->
310 -- There cannae be an ErrorHandle here
312 ioToST (writeHandle handle htype) >>
314 SemiClosedHandle fp (buf, size) ->
315 _ccall_ readLine buf fp size >>= \ bytes ->
318 else packCBytesST bytes buf) >>= \ some ->
320 _ccall_ free buf >>= \ () ->
321 _ccall_ closeFile fp >>
323 writeForeignObj fp ``NULL'' >>
324 ioToST (writeHandle handle (SemiClosedHandle fp (``NULL'', 0))) >>
326 ioToST (writeHandle handle (SemiClosedHandle ``NULL'' (``NULL'', 0))) >>
328 returnPrimIO (unpackPS some)
330 ioToST (writeHandle handle htype) >>
331 unsafeInterleavePrimIO (lazyReadLine handle)
333 returnPrimIO (unpackPS some ++ more)
335 lazyReadChar handle =
336 ioToST (readHandle handle) >>= \ htype ->
338 -- There cannae be an ErrorHandle here
340 ioToST (writeHandle handle htype) >>
342 SemiClosedHandle fp buf_info ->
343 _ccall_ readChar fp >>= \ char ->
344 if char == ``EOF'' then
345 _ccall_ closeFile fp >>
347 writeForeignObj fp ``NULL'' >>
348 ioToST (writeHandle handle (SemiClosedHandle fp (``NULL'', 0))) >>
350 ioToST (writeHandle handle (SemiClosedHandle ``NULL'' (``NULL'', 0))) >>
354 ioToST (writeHandle handle htype) >>
355 unsafeInterleavePrimIO (lazyReadChar handle)
357 returnPrimIO (chr char : more)
362 %*********************************************************
364 \subsection{Simple output functions}
366 %*********************************************************
368 Computation $hPutChar hdl c$ writes the character {\em c} to the file
369 or channel managed by {\em hdl}. Characters may be buffered if
370 buffering is enabled for {\em hdl}.
373 --hPutChar :: Handle -> Char -> IO ()
376 readHandle handle >>= \ htype ->
378 ErrorHandle ioError ->
379 writeHandle handle htype >>
382 writeHandle handle htype >>
383 ioe_closedHandle handle
384 SemiClosedHandle _ _ ->
385 writeHandle handle htype >>
386 ioe_closedHandle handle
388 writeHandle handle htype >>
389 fail (IOError (Just handle) IllegalOperation "handle is not open for writing")
391 _ccall_ filePutc (filePtr other) (ord c) `thenIO_Prim` \ rc ->
392 writeHandle handle (markHandle htype) >>
396 constructErrorAndFail "hPutChar"
399 Computation $hPutStr hdl s$ writes the string {\em s} to the file or
400 channel managed by {\em hdl}.
403 --hPutStr :: Handle -> String -> IO ()
406 readHandle handle >>= \ htype ->
408 ErrorHandle ioError ->
409 writeHandle handle htype >>
412 writeHandle handle htype >>
413 ioe_closedHandle handle
414 SemiClosedHandle _ _ ->
415 writeHandle handle htype >>
416 ioe_closedHandle handle
418 writeHandle handle htype >>
419 fail (IOError (Just handle) IllegalOperation "handle is not open for writing")
422 The code below is not correct for line-buffered terminal streams,
423 as the output stream is not flushed when terminal input is requested
424 again, just upon seeing a newline character. A temporary fix for the
425 most common line-buffered output stream, stdout, is to assume the
426 buffering it was given when created (no buffering). This is not
427 as bad as it looks, since stdio buffering sits underneath this.
431 getBufferMode other `thenIO_Prim` \ other ->
432 (case bufferMode other of
433 Just LineBuffering ->
434 writeChars (filePtr other) str
435 --writeLines (filePtr other) str
436 Just (BlockBuffering (Just size)) ->
437 writeBlocks (filePtr other) size str
438 Just (BlockBuffering Nothing) ->
439 writeBlocks (filePtr other) ``BUFSIZ'' str
440 _ -> -- Nothing is treated pessimistically as NoBuffering
441 writeChars (filePtr other) str
442 ) `thenIO_Prim` \ success ->
443 writeHandle handle (markHandle other) >>
447 constructErrorAndFail "hPutStr"
450 writeLines :: ForeignObj -> String -> PrimIO Bool
452 writeLines :: Addr -> String -> PrimIO Bool
454 writeLines = writeChunks ``BUFSIZ'' True
457 writeBlocks :: ForeignObj -> Int -> String -> PrimIO Bool
459 writeBlocks :: Addr -> Int -> String -> PrimIO Bool
461 writeBlocks fp size s = writeChunks size False fp s
464 The breaking up of output into lines along \n boundaries
465 works fine as long as there are newlines to split by.
466 Avoid the splitting up into lines alltogether (doesn't work
467 for overly long lines like the stuff that showsPrec instances
468 normally return). Instead, we split them up into fixed size
469 chunks before blasting them off to the Real World.
471 Hacked to avoid multiple passes over the strings - unsightly, but
472 a whole lot quicker. -- SOF 3/96
476 writeChunks :: Int -> Bool -> ForeignObj -> String -> PrimIO Bool
478 writeChunks :: Int -> Bool -> Addr -> String -> PrimIO Bool
480 writeChunks (I# bufLen) chopOnNewLine fp s =
481 newCharArray (0,I# bufLen) >>= \ arr@(MutableByteArray _ arr#) ->
483 write_char :: MutableByteArray# RealWorld -> Int# -> Char# -> PrimIO ()
484 write_char arr# n x = ST $ \ (S# s#) ->
485 case (writeCharArray# arr# n x s#) of { s1# ->
488 shoveString :: Int# -> [Char] -> PrimIO Bool
495 _ccall_ writeFile arr fp (I# n) >>= \rc ->
499 write_char arr# n x >>
501 {- Flushing lines - should we bother? Yes, for line-buffered output. -}
502 if n ==# bufLen || (chopOnNewLine && (x `eqChar#` '\n'#)) then
503 _ccall_ writeFile arr fp (I# (n +# 1#)) >>= \ rc ->
509 shoveString (n +# 1#) xs
514 writeChars :: ForeignObj -> String -> PrimIO Bool
516 writeChars :: Addr -> String -> PrimIO Bool
518 writeChars fp "" = returnPrimIO True
519 writeChars fp (c:cs) =
520 _ccall_ filePutc fp (ord c) >>= \ rc ->
527 Computation $hPrint hdl t$ writes the string representation of {\em t}
528 given by the $shows$ function to the file or channel managed by {\em
531 SOF 2/97: Seem to have disappeared in 1.4 libs.
534 --hPrint :: Show a => Handle -> a -> IO ()
535 hPrint hdl = hPutStr hdl . show
538 Derived action @hPutStrLn hdl str@ writes the string \tr{str} to
539 the handle \tr{hdl}, adding a newline at the end.
542 --hPutStrLn :: Handle -> String -> IO ()
543 hPutStrLn hndl str = do