2 % (c) The GRAP/AQUA Project, Glasgow University, 1992-1996
4 \section[PrelIO]{Module @PrelIO@}
6 This module defines all basic IO operations.
7 These are needed for the IO operations exported by Prelude,
8 but as it happens they also do everything required by library
13 {-# OPTIONS -fno-implicit-prelude -#include "cbits/stgio.h" #-}
20 import PrelHandle -- much of the real stuff is in here
23 import PrelRead ( readParen, Read(..), reads, lex, readIO )
25 import PrelMaybe ( Either(..), Maybe(..) )
26 import PrelAddr ( Addr(..), AddrOff(..), nullAddr, plusAddr )
27 import PrelList ( concat, reverse, null )
28 import PrelByteArr ( ByteArray )
29 import PrelPack ( unpackNBytesST, unpackNBytesAccST )
30 import PrelException ( ioError, catch, catchException, throw,
31 blockAsyncExceptions )
36 %*********************************************************
38 \subsection{Standard IO}
40 %*********************************************************
42 The Prelude has from Day 1 provided a collection of common
43 IO functions. We define these here, but let the Prelude
47 putChar :: Char -> IO ()
48 putChar c = hPutChar stdout c
50 putStr :: String -> IO ()
51 putStr s = hPutStr stdout s
53 putStrLn :: String -> IO ()
54 putStrLn s = do putStr s
57 print :: Show a => a -> IO ()
58 print x = putStrLn (show x)
61 getChar = hGetChar stdin
64 getLine = hGetLine stdin
66 getContents :: IO String
67 getContents = hGetContents stdin
69 interact :: (String -> String) -> IO ()
70 interact f = do s <- getContents
73 readFile :: FilePath -> IO String
74 readFile name = openFile name ReadMode >>= hGetContents
76 writeFile :: FilePath -> String -> IO ()
77 writeFile name str = do
78 hdl <- openFile name WriteMode
82 appendFile :: FilePath -> String -> IO ()
83 appendFile name str = do
84 hdl <- openFile name AppendMode
88 readLn :: Read a => IO a
89 readLn = do l <- getLine
95 %*********************************************************
97 \subsection{Simple input operations}
99 %*********************************************************
101 Computation @hReady hdl@ indicates whether at least
102 one item is available for input from handle {\em hdl}.
104 @hWaitForInput@ is the generalisation, wait for \tr{n} milliseconds
105 before deciding whether the Handle has run dry or not.
107 If @hWaitForInput@ finds anything in the Handle's buffer, it immediately returns.
108 If not, it tries to read from the underlying OS handle. Notice that
109 for buffered Handles connected to terminals this means waiting until a complete
113 hReady :: Handle -> IO Bool
114 hReady h = hWaitForInput h 0
116 hWaitForInput :: Handle -> Int -> IO Bool
117 hWaitForInput handle msecs =
118 wantReadableHandle "hWaitForInput" handle $ \ handle_ -> do
119 rc <- inputReady (haFO__ handle_) (msecs::Int) -- ConcHask: SAFE, won't block
123 _ -> constructErrorAndFail "hWaitForInput"
126 @hGetChar hdl@ reads the next character from handle @hdl@,
127 blocking until a character is available.
130 hGetChar :: Handle -> IO Char
132 c <- mayBlockRead "hGetChar" handle fileGetc
136 If EOF is reached before EOL is encountered, ignore the
137 EOF and return the partial line. Next attempt at calling
138 hGetLine on the handle will yield an EOF IO exception though.
141 hGetLine :: Handle -> IO String
142 hGetLine h = hGetLineBuf' []
143 where hGetLineBuf' xss = do
146 mayBlockRead' "hGetLine" h
149 buf <- getBufStart fo bytes
150 eol <- readCharOffAddr buf (bytes-1)
151 xs <- if (eol == '\n')
152 then stToIO (unpackNBytesST buf (bytes-1))
153 else stToIO (unpackNBytesST buf bytes)
157 (\e -> if isEOFError e && not (null xss)
158 then return ('\n', xss)
162 then return (concat (reverse xss))
163 else hGetLineBuf' xss
165 readCharOffAddr (A# a) (I# i)
166 = IO $ \s -> case readCharOffAddr# a i s of { (# s,x #) -> (# s, C# x #) }
169 @hLookahead hdl@ returns the next character from handle @hdl@
170 without removing it from the input buffer, blocking until a
171 character is available.
174 hLookAhead :: Handle -> IO Char
175 hLookAhead handle = do
176 rc <- mayBlockRead "hLookAhead" handle fileLookAhead
181 %*********************************************************
183 \subsection{Getting the entire contents of a handle}
185 %*********************************************************
187 @hGetContents hdl@ returns the list of characters corresponding
188 to the unread portion of the channel or file managed by @hdl@,
189 which is made semi-closed.
192 hGetContents :: Handle -> IO String
193 hGetContents handle =
194 -- can't use wantReadableHandle here, because we want to side effect
196 withHandle handle $ \ handle_ -> do
197 case haType__ handle_ of
198 ErrorHandle theError -> ioError theError
199 ClosedHandle -> ioe_closedHandle "hGetContents" handle
200 SemiClosedHandle -> ioe_closedHandle "hGetContents" handle
201 AppendHandle -> ioError not_readable_error
202 WriteHandle -> ioError not_readable_error
205 To avoid introducing an extra layer of buffering here,
206 we provide three lazy read methods, based on character,
207 line, and block buffering.
209 let handle_' = handle_{ haType__ = SemiClosedHandle }
210 case (haBufferMode__ handle_) of
212 str <- unsafeInterleaveIO (lazyReadLine handle (haFO__ handle_))
213 return (handle_', str)
214 BlockBuffering _ -> do
215 str <- unsafeInterleaveIO (lazyReadBlock handle (haFO__ handle_))
216 return (handle_', str)
218 str <- unsafeInterleaveIO (lazyReadChar handle (haFO__ handle_))
219 return (handle_', str)
222 IOError (Just handle) IllegalOperation "hGetContents"
223 ("handle is not open for reading")
226 Note that someone may close the semi-closed handle (or change its buffering),
227 so each these lazy read functions are pulled on, they have to check whether
228 the handle has indeed been closed.
231 #ifndef __PARALLEL_HASKELL__
232 lazyReadBlock :: Handle -> ForeignObj -> IO String
233 lazyReadLine :: Handle -> ForeignObj -> IO String
234 lazyReadChar :: Handle -> ForeignObj -> IO String
236 lazyReadBlock :: Handle -> Addr -> IO String
237 lazyReadLine :: Handle -> Addr -> IO String
238 lazyReadChar :: Handle -> Addr -> IO String
241 lazyReadBlock handle fo = do
242 buf <- getBufStart fo 0
243 bytes <- mayBlock fo (readBlock fo) -- ConcHask: UNSAFE, may block.
245 -3 -> -- buffering has been turned off, use lazyReadChar instead
246 lazyReadChar handle fo
248 -1 -> -- an error occurred, close the handle
249 withHandle handle $ \ handle_ -> do
250 closeFile (haFO__ handle_) 0{-don't bother flushing-} -- ConcHask: SAFE, won't block.
251 return (handle_ { haType__ = ClosedHandle,
252 haFO__ = nullFile__ },
255 more <- unsafeInterleaveIO (lazyReadBlock handle fo)
256 stToIO (unpackNBytesAccST buf bytes more)
258 lazyReadLine handle fo = do
259 bytes <- mayBlock fo (readLine fo) -- ConcHask: UNSAFE, may block.
261 -3 -> -- buffering has been turned off, use lazyReadChar instead
262 lazyReadChar handle fo
263 -2 -> return "" -- handle closed by someone else, stop reading.
264 -1 -> -- an error occurred, close the handle
265 withHandle handle $ \ handle_ -> do
266 closeFile (haFO__ handle_) 0{- don't bother flushing-} -- ConcHask: SAFE, won't block
267 return (handle_ { haType__ = ClosedHandle,
268 haFO__ = nullFile__ },
271 more <- unsafeInterleaveIO (lazyReadLine handle fo)
272 buf <- getBufStart fo bytes -- ConcHask: won't block
273 stToIO (unpackNBytesAccST buf bytes more)
275 lazyReadChar handle fo = do
276 char <- mayBlock fo (readChar fo) -- ConcHask: UNSAFE, may block.
278 -4 -> -- buffering is now block-buffered, use lazyReadBlock instead
279 lazyReadBlock handle fo
281 -3 -> -- buffering is now line-buffered, use lazyReadLine instead
282 lazyReadLine handle fo
284 -1 -> -- error, silently close handle.
285 withHandle handle $ \ handle_ -> do
286 closeFile (haFO__ handle_) 0{-don't bother flusing-} -- ConcHask: SAFE, won't block
287 return (handle_{ haType__ = ClosedHandle,
288 haFO__ = nullFile__ },
291 more <- unsafeInterleaveIO (lazyReadChar handle fo)
292 return (chr char : more)
297 %*********************************************************
299 \subsection{Simple output functions}
301 %*********************************************************
303 @hPutChar hdl ch@ writes the character @ch@ to the file
304 or channel managed by @hdl@. Characters may be buffered if
305 buffering is enabled for @hdl@
308 hPutChar :: Handle -> Char -> IO ()
310 c `seq` do -- must evaluate c before grabbing the handle lock
311 wantWriteableHandle "hPutChar" handle $ \ handle_ -> do
312 let fo = haFO__ handle_
314 rc <- mayBlock fo (filePutc fo c) -- ConcHask: UNSAFE, may block.
317 else constructErrorAndFail "hPutChar"
319 hPutChars :: Handle -> [Char] -> IO ()
320 hPutChars handle [] = return ()
321 hPutChars handle (c:cs) = hPutChar handle c >> hPutChars handle cs
324 @hPutStr hdl s@ writes the string @s@ to the file or
325 channel managed by @hdl@, buffering the output if needs be.
329 hPutStr :: Handle -> String -> IO ()
330 hPutStr handle str = do
331 buffer_mode <- wantWriteableHandle_ "hPutStr" handle
332 (\ handle_ -> do getBuffer handle_)
334 (NoBuffering, _, _) -> do
335 hPutChars handle str -- v. slow, but we don't care
336 (LineBuffering, buf, bsz) -> do
337 writeLines handle buf bsz str
338 (BlockBuffering _, buf, bsz) -> do
339 writeBlocks handle buf bsz str
340 -- ToDo: async exceptions during writeLines & writeBlocks will cause
341 -- the buffer to get lost in the void. Using ByteArrays instead of
342 -- malloced buffers is one way around this, but we really ought to
343 -- be able to handle it with exception handlers/block/unblock etc.
345 getBuffer :: Handle__ -> IO (Handle__, (BufferMode, Addr, Int))
346 getBuffer handle_ = do
347 let bufs = haBuffers__ handle_
349 mode = haBufferMode__ handle_
352 NoBuffering -> return (handle_, (mode, nullAddr, 0))
354 [] -> do buf <- allocMemory__ sz
355 return (handle_, (mode, buf, sz))
356 (b:bs) -> return (handle_{ haBuffers__ = bs }, (mode, b, sz))
358 freeBuffer :: Handle__ -> Addr -> Int -> IO Handle__
359 freeBuffer handle_ buf sz = do
360 fo_sz <- getBufSize (haFO__ handle_)
362 then do { free buf; return handle_ }
363 else do { return handle_{ haBuffers__ = buf : haBuffers__ handle_ } }
365 swapBuffers :: Handle__ -> Addr -> Int -> IO Handle__
366 swapBuffers handle_ buf sz = do
367 let fo = haFO__ handle_
370 return (handle_{ haBuffers__ = fo_buf : haBuffers__ handle_ })
372 -------------------------------------------------------------------------------
373 -- commitAndReleaseBuffer handle buf sz count flush
375 -- Write the contents of the buffer 'buf' ('sz' bytes long, containing
376 -- 'count' bytes of data) to handle (handle must be block or line buffered).
380 -- for block/line buffering,
381 -- 1. If there isn't room in the handle buffer, flush the handle
384 -- 2. If the handle buffer is empty,
386 -- then write buf directly to the device.
387 -- else swap the handle buffer with buf.
389 -- 3. If the handle buffer is non-empty, copy buf into the
390 -- handle buffer. Then, if flush != 0, flush
393 commitAndReleaseBuffer
394 :: Handle -- handle to commit to
395 -> Addr -> Int -- address and size (in bytes) of buffer
396 -> Int -- number of bytes of data in buffer
397 -> Bool -- flush the handle afterward?
400 commitAndReleaseBuffer hdl@(Handle h) buf sz count flush = do
403 -- First deal with any possible exceptions, by freeing the buffer.
404 -- Async exceptions are blocked, but there are still some interruptible
407 -- note that commit doesn't *always* free the buffer, it might
408 -- swap it for the current handle buffer instead. This makes things
409 -- a whole lot more complicated, because we can't just do
410 -- "finally (... free buffer ...)" here.
411 catchException (commit hdl h_)
412 (\e -> do { h_ <- freeBuffer h_ buf sz; putMVar h h_ })
415 commit hdl@(Handle h) handle_ =
416 checkWriteableHandle "commitAndReleaseBuffer" hdl handle_ $ do
417 let fo = haFO__ handle_
418 flushConnectedBuf fo -- ???? -SDM
419 getWriteableBuf fo -- flush read buf if necessary
421 fo_wptr <- getBufWPtr fo
422 fo_bufSize <- getBufSize fo
424 let ok h_ = putMVar h h_ >> return ()
426 -- enough room in handle buffer for the new data?
427 if (flush || fo_bufSize - fo_wptr <= count)
429 -- The <= is to be sure that we never exactly fill up the
430 -- buffer, which would require a flush. So if copying the
431 -- new data into the buffer would make the buffer full, we
432 -- just flush the existing buffer and the new data immediately,
433 -- rather than copying before flushing.
435 then do rc <- mayBlock fo (flushFile fo)
437 then constructErrorAndFail "commitAndReleaseBuffer"
439 if (flush || sz /= fo_bufSize || count == sz)
440 then do rc <- write_buf fo buf count
442 then constructErrorAndFail "commitAndReleaseBuffer"
443 else do handle_ <- freeBuffer handle_ buf sz
446 -- if: (a) we don't have to flush, and
447 -- (b) size(new buffer) == size(old buffer), and
448 -- (c) new buffer is not full,
449 -- we can just just swap them over...
450 else do handle_ <- swapBuffers handle_ buf sz
454 -- not flushing, and there's enough room in the buffer:
455 -- just copy the data in and update bufWPtr.
456 else do memcpy (plusAddr fo_buf (AddrOff# fo_wptr)) buf count
457 setBufWPtr fo (fo_wptr + count)
458 handle_ <- freeBuffer handle_ buf sz
461 --------------------------------------------------------------------------------
462 -- commitBuffer handle buf sz count flush
464 -- Flushes 'count' bytes from the buffer 'buf' (size 'sz') to 'handle'.
465 -- There are several cases to consider altogether:
468 -- - flush handle buffer,
469 -- - write out new buffer directly
472 -- - if there's enough room in the handle buffer,
473 -- then copy new buf into it
474 -- else flush handle buffer, then copy new buffer into it
476 -- Make sure that we maintain the invariant that the handle buffer is never
477 -- left in a full state. Several functions rely on this (eg. filePutc), so
478 -- if we're about to exactly fill the buffer then we make sure we do a flush
479 -- here (also see above in commitAndReleaseBuffer).
482 :: Handle -- handle to commit to
483 -> Addr -> Int -- address and size (in bytes) of buffer
484 -> Int -- number of bytes of data in buffer
485 -> Bool -- flush the handle afterward?
488 commitBuffer handle buf sz count flush = do
489 wantWriteableHandle "commitBuffer" handle $ \handle_ -> do
490 let fo = haFO__ handle_
491 flushConnectedBuf fo -- ???? -SDM
492 getWriteableBuf fo -- flush read buf if necessary
494 fo_wptr <- getBufWPtr fo
495 fo_bufSize <- getBufSize fo
497 new_wptr <- -- not enough room in handle buffer?
498 (if flush || (fo_bufSize - fo_wptr <= count)
499 then do rc <- mayBlock fo (flushFile fo)
500 if (rc < 0) then constructErrorAndFail "commitBuffer"
502 else return fo_wptr )
504 if (flush || fo_bufSize <= count) -- committed buffer too large?
506 then do rc <- write_buf fo buf count
507 if (rc < 0) then constructErrorAndFail "commitBuffer"
510 else do memcpy (plusAddr fo_buf (AddrOff# new_wptr)) buf count
511 setBufWPtr fo (new_wptr + count)
514 write_buf fo buf 0 = return 0
515 write_buf fo buf count = do
516 rc <- mayBlock fo (write_ fo buf count)
518 then write_buf fo buf (count - rc) -- partial write
521 -- a version of commitBuffer that will free the buffer if an exception is
522 -- received. DON'T use this if you intend to use the buffer again!
523 checkedCommitBuffer handle buf sz count flush
524 = catchException (commitBuffer handle buf sz count flush)
525 (\e -> do withHandle__ handle (\h_ -> freeBuffer h_ buf sz)
528 foreign import "memcpy" unsafe memcpy :: Addr -> Addr -> Int -> IO ()
531 Going across the border between Haskell and C is relatively costly,
532 so for block writes we pack the character strings on the Haskell-side
533 before passing the external write routine a pointer to the buffer.
538 #ifdef __CONCURRENT_HASKELL__
539 /* See comment in shoveString below for explanation */
540 #warning delayed update of buffer disnae work with killThread
543 writeLines :: Handle -> Addr -> Int -> String -> IO ()
544 writeLines handle buf bufLen s =
546 shoveString :: Int -> [Char] -> IO ()
549 [] -> commitAndReleaseBuffer handle buf buflen n False{-no need to flush-}
552 primWriteCharOffAddr buf n x
553 {- Flushing on buffer exhaustion or newlines (even if it isn't the last one) -}
555 if next_n == bufLen || x == '\n'
557 checkedCommitBuffer hdl buf len next_n True{-needs flush-}
560 shoveString next_n xs
564 #else /* ndef __HUGS__ */
566 writeLines :: Handle -> Addr -> Int -> String -> IO ()
567 writeLines hdl buf len@(I# bufLen) s =
569 shoveString :: Int# -> [Char] -> IO ()
572 [] -> commitAndReleaseBuffer hdl buf len (I# n) False{-no need to flush-}
576 -- Flushing on buffer exhaustion or newlines
577 -- (even if it isn't the last one)
579 if next_n ==# bufLen || x `eqChar#` '\n'#
581 checkedCommitBuffer hdl buf len (I# next_n) True{-needs flush-}
584 shoveString next_n xs
587 #endif /* ndef __HUGS__ */
590 writeBlocks :: Handle -> Addr -> Int -> String -> IO ()
591 writeBlocks hdl buf bufLen s =
593 shoveString :: Int -> [Char] -> IO ()
596 [] -> commitAndReleaseBuffer hdl buf len n False{-no need to flush-}
599 primWriteCharOffAddr buf n x
603 checkedCommitBuffer hdl buf len next_n True{-needs flush-}
606 shoveString next_n xs
610 #else /* ndef __HUGS__ */
612 writeBlocks :: Handle -> Addr -> Int -> String -> IO ()
613 writeBlocks hdl buf len@(I# bufLen) s =
615 shoveString :: Int# -> [Char] -> IO ()
618 [] -> commitAndReleaseBuffer hdl buf len (I# n) False{-no need to flush-}
625 checkedCommitBuffer hdl buf len (I# next_n) True{-needs flush-}
628 shoveString next_n xs
632 write_char :: Addr -> Int# -> Char# -> IO ()
633 write_char (A# buf#) n# c# =
635 case (writeCharOffAddr# buf# n# c# s#) of s2# -> (# s2#, () #)
636 #endif /* ndef __HUGS__ */
639 Computation @hPrint hdl t@ writes the string representation of {\em t}
640 given by the @shows@ function to the file or channel managed by {\em
643 [ Seem to have disappeared from the 1.4 interface - SOF 2/97 ]
646 hPrint :: Show a => Handle -> a -> IO ()
647 hPrint hdl = hPutStrLn hdl . show
650 Derived action @hPutStrLn hdl str@ writes the string \tr{str} to
651 the handle \tr{hdl}, adding a newline at the end.
654 hPutStrLn :: Handle -> String -> IO ()
655 hPutStrLn hndl str = do