1 % ------------------------------------------------------------------------------
2 % $Id: PrelIO.lhs,v 1.14 2000/07/07 11:03:58 simonmar Exp $
4 % (c) The University of Glasgow, 1992-2000
7 \section[PrelIO]{Module @PrelIO@}
9 This module defines all basic IO operations.
10 These are needed for the IO operations exported by Prelude,
11 but as it happens they also do everything required by library
16 {-# OPTIONS -fno-implicit-prelude -#include "cbits/stgio.h" #-}
23 import PrelHandle -- much of the real stuff is in here
26 import PrelRead ( Read(..), readIO )
28 import PrelMaybe ( Maybe(..) )
29 import PrelAddr ( Addr(..), AddrOff(..), nullAddr, plusAddr )
30 import PrelList ( concat, reverse, null )
31 import PrelPack ( unpackNBytesST, unpackNBytesAccST )
32 import PrelException ( ioError, catch, catchException, throw )
37 %*********************************************************
39 \subsection{Standard IO}
41 %*********************************************************
43 The Prelude has from Day 1 provided a collection of common
44 IO functions. We define these here, but let the Prelude
48 putChar :: Char -> IO ()
49 putChar c = hPutChar stdout c
51 putStr :: String -> IO ()
52 putStr s = hPutStr stdout s
54 putStrLn :: String -> IO ()
55 putStrLn s = do putStr s
58 print :: Show a => a -> IO ()
59 print x = putStrLn (show x)
62 getChar = hGetChar stdin
65 getLine = hGetLine stdin
67 getContents :: IO String
68 getContents = hGetContents stdin
70 interact :: (String -> String) -> IO ()
71 interact f = do s <- getContents
74 readFile :: FilePath -> IO String
75 readFile name = openFile name ReadMode >>= hGetContents
77 writeFile :: FilePath -> String -> IO ()
78 writeFile name str = do
79 hdl <- openFile name WriteMode
83 appendFile :: FilePath -> String -> IO ()
84 appendFile name str = do
85 hdl <- openFile name AppendMode
89 readLn :: Read a => IO a
90 readLn = do l <- getLine
96 %*********************************************************
98 \subsection{Simple input operations}
100 %*********************************************************
102 Computation @hReady hdl@ indicates whether at least
103 one item is available for input from handle {\em hdl}.
105 @hWaitForInput@ is the generalisation, wait for \tr{n} milliseconds
106 before deciding whether the Handle has run dry or not.
108 If @hWaitForInput@ finds anything in the Handle's buffer, it immediately returns.
109 If not, it tries to read from the underlying OS handle. Notice that
110 for buffered Handles connected to terminals this means waiting until a complete
114 hReady :: Handle -> IO Bool
115 hReady h = hWaitForInput h 0
117 hWaitForInput :: Handle -> Int -> IO Bool
118 hWaitForInput handle msecs =
119 wantReadableHandle "hWaitForInput" handle $ \ handle_ -> do
120 rc <- inputReady (haFO__ handle_) (msecs::Int) -- ConcHask: SAFE, won't block
124 _ -> constructErrorAndFail "hWaitForInput"
127 @hGetChar hdl@ reads the next character from handle @hdl@,
128 blocking until a character is available.
131 hGetChar :: Handle -> IO Char
133 c <- mayBlockRead "hGetChar" handle fileGetc
137 If EOF is reached before EOL is encountered, ignore the
138 EOF and return the partial line. Next attempt at calling
139 hGetLine on the handle will yield an EOF IO exception though.
142 hGetLine :: Handle -> IO String
144 buffer_mode <- wantReadableHandle "hGetLine" h
145 (\ handle_ -> do return (haBufferMode__ handle_))
147 NoBuffering -> hGetLineUnBuffered h
148 LineBuffering -> hGetLineBuf' []
149 BlockBuffering _ -> hGetLineBuf' []
151 where hGetLineBuf' xss = do
154 mayBlockRead' "hGetLine" h
157 buf <- getBufStart fo bytes
158 eol <- readCharOffAddr buf (bytes-1)
159 xs <- if (eol == '\n')
160 then stToIO (unpackNBytesST buf (bytes-1))
161 else stToIO (unpackNBytesST buf bytes)
165 (\e -> if isEOFError e && not (null xss)
166 then return ('\n', xss)
170 then return (concat (reverse xss))
171 else hGetLineBuf' xss
174 hGetLineUnBuffered :: Handle -> IO String
175 hGetLineUnBuffered h = do
188 if isEOFError err then
199 readCharOffAddr (A# a) (I# i)
200 = IO $ \s -> case readCharOffAddr# a i s of { (# s,x #) -> (# s, C# x #) }
203 @hLookahead hdl@ returns the next character from handle @hdl@
204 without removing it from the input buffer, blocking until a
205 character is available.
208 hLookAhead :: Handle -> IO Char
209 hLookAhead handle = do
210 rc <- mayBlockRead "hLookAhead" handle fileLookAhead
215 %*********************************************************
217 \subsection{Getting the entire contents of a handle}
219 %*********************************************************
221 @hGetContents hdl@ returns the list of characters corresponding
222 to the unread portion of the channel or file managed by @hdl@,
223 which is made semi-closed.
226 hGetContents :: Handle -> IO String
227 hGetContents handle =
228 -- can't use wantReadableHandle here, because we want to side effect
230 withHandle handle $ \ handle_ -> do
231 case haType__ handle_ of
232 ErrorHandle theError -> ioException theError
233 ClosedHandle -> ioe_closedHandle "hGetContents" handle
234 SemiClosedHandle -> ioe_closedHandle "hGetContents" handle
235 AppendHandle -> ioException not_readable_error
236 WriteHandle -> ioException not_readable_error
239 To avoid introducing an extra layer of buffering here,
240 we provide three lazy read methods, based on character,
241 line, and block buffering.
243 let handle_' = handle_{ haType__ = SemiClosedHandle }
244 case (haBufferMode__ handle_) of
246 str <- unsafeInterleaveIO (lazyReadLine handle (haFO__ handle_))
247 return (handle_', str)
248 BlockBuffering _ -> do
249 str <- unsafeInterleaveIO (lazyReadBlock handle (haFO__ handle_))
250 return (handle_', str)
252 str <- unsafeInterleaveIO (lazyReadChar handle (haFO__ handle_))
253 return (handle_', str)
256 IOError (Just handle) IllegalOperation "hGetContents"
257 ("handle is not open for reading")
260 Note that someone may close the semi-closed handle (or change its buffering),
261 so each these lazy read functions are pulled on, they have to check whether
262 the handle has indeed been closed.
265 #ifndef __PARALLEL_HASKELL__
266 lazyReadBlock :: Handle -> ForeignObj -> IO String
267 lazyReadLine :: Handle -> ForeignObj -> IO String
268 lazyReadChar :: Handle -> ForeignObj -> IO String
270 lazyReadBlock :: Handle -> Addr -> IO String
271 lazyReadLine :: Handle -> Addr -> IO String
272 lazyReadChar :: Handle -> Addr -> IO String
275 lazyReadBlock handle fo = do
276 buf <- getBufStart fo 0
277 bytes <- mayBlock fo (readBlock fo) -- ConcHask: UNSAFE, may block.
279 -3 -> -- buffering has been turned off, use lazyReadChar instead
280 lazyReadChar handle fo
282 -1 -> -- an error occurred, close the handle
283 withHandle handle $ \ handle_ -> do
284 closeFile (haFO__ handle_) 0{-don't bother flushing-} -- ConcHask: SAFE, won't block.
285 return (handle_ { haType__ = ClosedHandle,
286 haFO__ = nullFile__ },
289 more <- unsafeInterleaveIO (lazyReadBlock handle fo)
290 stToIO (unpackNBytesAccST buf bytes more)
292 lazyReadLine handle fo = do
293 bytes <- mayBlock fo (readLine fo) -- ConcHask: UNSAFE, may block.
295 -3 -> -- buffering has been turned off, use lazyReadChar instead
296 lazyReadChar handle fo
297 -2 -> return "" -- handle closed by someone else, stop reading.
298 -1 -> -- an error occurred, close the handle
299 withHandle handle $ \ handle_ -> do
300 closeFile (haFO__ handle_) 0{- don't bother flushing-} -- ConcHask: SAFE, won't block
301 return (handle_ { haType__ = ClosedHandle,
302 haFO__ = nullFile__ },
305 more <- unsafeInterleaveIO (lazyReadLine handle fo)
306 buf <- getBufStart fo bytes -- ConcHask: won't block
307 stToIO (unpackNBytesAccST buf bytes more)
309 lazyReadChar handle fo = do
310 char <- mayBlock fo (readChar fo) -- ConcHask: UNSAFE, may block.
312 -4 -> -- buffering is now block-buffered, use lazyReadBlock instead
313 lazyReadBlock handle fo
315 -3 -> -- buffering is now line-buffered, use lazyReadLine instead
316 lazyReadLine handle fo
318 -1 -> -- error, silently close handle.
319 withHandle handle $ \ handle_ -> do
320 closeFile (haFO__ handle_) 0{-don't bother flusing-} -- ConcHask: SAFE, won't block
321 return (handle_{ haType__ = ClosedHandle,
322 haFO__ = nullFile__ },
325 more <- unsafeInterleaveIO (lazyReadChar handle fo)
326 return (chr char : more)
331 %*********************************************************
333 \subsection{Simple output functions}
335 %*********************************************************
337 @hPutChar hdl ch@ writes the character @ch@ to the file
338 or channel managed by @hdl@. Characters may be buffered if
339 buffering is enabled for @hdl@
342 hPutChar :: Handle -> Char -> IO ()
344 c `seq` do -- must evaluate c before grabbing the handle lock
345 wantWriteableHandle "hPutChar" handle $ \ handle_ -> do
346 let fo = haFO__ handle_
348 rc <- mayBlock fo (filePutc fo c) -- ConcHask: UNSAFE, may block.
351 else constructErrorAndFail "hPutChar"
353 hPutChars :: Handle -> [Char] -> IO ()
354 hPutChars handle [] = return ()
355 hPutChars handle (c:cs) = hPutChar handle c >> hPutChars handle cs
358 @hPutStr hdl s@ writes the string @s@ to the file or
359 channel managed by @hdl@, buffering the output if needs be.
363 hPutStr :: Handle -> String -> IO ()
364 hPutStr handle str = do
365 buffer_mode <- wantWriteableHandle_ "hPutStr" handle
366 (\ handle_ -> do getBuffer handle_)
368 (NoBuffering, _, _) -> do
369 hPutChars handle str -- v. slow, but we don't care
370 (LineBuffering, buf, bsz) -> do
371 writeLines handle buf bsz str
372 (BlockBuffering _, buf, bsz) -> do
373 writeBlocks handle buf bsz str
374 -- ToDo: async exceptions during writeLines & writeBlocks will cause
375 -- the buffer to get lost in the void. Using ByteArrays instead of
376 -- malloced buffers is one way around this, but we really ought to
377 -- be able to handle it with exception handlers/block/unblock etc.
379 getBuffer :: Handle__ -> IO (Handle__, (BufferMode, Addr, Int))
380 getBuffer handle_ = do
381 let bufs = haBuffers__ handle_
383 mode = haBufferMode__ handle_
386 NoBuffering -> return (handle_, (mode, nullAddr, 0))
388 [] -> do buf <- allocMemory__ sz
389 return (handle_, (mode, buf, sz))
390 (b:bs) -> return (handle_{ haBuffers__ = bs }, (mode, b, sz))
392 freeBuffer :: Handle__ -> Addr -> Int -> IO Handle__
393 freeBuffer handle_ buf sz = do
394 fo_sz <- getBufSize (haFO__ handle_)
396 then do { free buf; return handle_ }
397 else do { return handle_{ haBuffers__ = buf : haBuffers__ handle_ } }
399 swapBuffers :: Handle__ -> Addr -> Int -> IO Handle__
400 swapBuffers handle_ buf sz = do
401 let fo = haFO__ handle_
404 return (handle_{ haBuffers__ = fo_buf : haBuffers__ handle_ })
406 -------------------------------------------------------------------------------
407 -- commitAndReleaseBuffer handle buf sz count flush
409 -- Write the contents of the buffer 'buf' ('sz' bytes long, containing
410 -- 'count' bytes of data) to handle (handle must be block or line buffered).
414 -- for block/line buffering,
415 -- 1. If there isn't room in the handle buffer, flush the handle
418 -- 2. If the handle buffer is empty,
420 -- then write buf directly to the device.
421 -- else swap the handle buffer with buf.
423 -- 3. If the handle buffer is non-empty, copy buf into the
424 -- handle buffer. Then, if flush != 0, flush
427 commitAndReleaseBuffer
428 :: Handle -- handle to commit to
429 -> Addr -> Int -- address and size (in bytes) of buffer
430 -> Int -- number of bytes of data in buffer
431 -> Bool -- flush the handle afterward?
434 commitAndReleaseBuffer hdl@(Handle h) buf sz count flush = do
437 -- First deal with any possible exceptions, by freeing the buffer.
438 -- Async exceptions are blocked, but there are still some interruptible
441 -- note that commit doesn't *always* free the buffer, it might
442 -- swap it for the current handle buffer instead. This makes things
443 -- a whole lot more complicated, because we can't just do
444 -- "finally (... free buffer ...)" here.
445 catchException (commit hdl h_)
446 (\e -> do { h_ <- freeBuffer h_ buf sz; putMVar h h_ })
449 commit hdl@(Handle h) handle_ =
450 checkWriteableHandle "commitAndReleaseBuffer" hdl handle_ $ do
451 let fo = haFO__ handle_
452 flushConnectedBuf fo -- ???? -SDM
453 getWriteableBuf fo -- flush read buf if necessary
455 fo_wptr <- getBufWPtr fo
456 fo_bufSize <- getBufSize fo
458 let ok h_ = putMVar h h_ >> return ()
460 -- enough room in handle buffer for the new data?
461 if (flush || fo_bufSize - fo_wptr <= count)
463 -- The <= is to be sure that we never exactly fill up the
464 -- buffer, which would require a flush. So if copying the
465 -- new data into the buffer would make the buffer full, we
466 -- just flush the existing buffer and the new data immediately,
467 -- rather than copying before flushing.
469 then do rc <- mayBlock fo (flushFile fo)
471 then constructErrorAndFail "commitAndReleaseBuffer"
473 if (flush || sz /= fo_bufSize || count == sz)
474 then do rc <- write_buf fo buf count
476 then constructErrorAndFail "commitAndReleaseBuffer"
477 else do handle_ <- freeBuffer handle_ buf sz
480 -- if: (a) we don't have to flush, and
481 -- (b) size(new buffer) == size(old buffer), and
482 -- (c) new buffer is not full,
483 -- we can just just swap them over...
484 else do handle_ <- swapBuffers handle_ buf sz
488 -- not flushing, and there's enough room in the buffer:
489 -- just copy the data in and update bufWPtr.
490 else do memcpy (plusAddr fo_buf (AddrOff# fo_wptr)) buf count
491 setBufWPtr fo (fo_wptr + count)
492 handle_ <- freeBuffer handle_ buf sz
495 --------------------------------------------------------------------------------
496 -- commitBuffer handle buf sz count flush
498 -- Flushes 'count' bytes from the buffer 'buf' (size 'sz') to 'handle'.
499 -- There are several cases to consider altogether:
502 -- - flush handle buffer,
503 -- - write out new buffer directly
506 -- - if there's enough room in the handle buffer,
507 -- then copy new buf into it
508 -- else flush handle buffer, then copy new buffer into it
510 -- Make sure that we maintain the invariant that the handle buffer is never
511 -- left in a full state. Several functions rely on this (eg. filePutc), so
512 -- if we're about to exactly fill the buffer then we make sure we do a flush
513 -- here (also see above in commitAndReleaseBuffer).
516 :: Handle -- handle to commit to
517 -> Addr -> Int -- address and size (in bytes) of buffer
518 -> Int -- number of bytes of data in buffer
519 -> Bool -- flush the handle afterward?
522 commitBuffer handle buf sz count flush = do
523 wantWriteableHandle "commitBuffer" handle $ \handle_ -> do
524 let fo = haFO__ handle_
525 flushConnectedBuf fo -- ???? -SDM
526 getWriteableBuf fo -- flush read buf if necessary
528 fo_wptr <- getBufWPtr fo
529 fo_bufSize <- getBufSize fo
531 new_wptr <- -- not enough room in handle buffer?
532 (if flush || (fo_bufSize - fo_wptr <= count)
533 then do rc <- mayBlock fo (flushFile fo)
534 if (rc < 0) then constructErrorAndFail "commitBuffer"
536 else return fo_wptr )
538 if (flush || fo_bufSize <= count) -- committed buffer too large?
540 then do rc <- write_buf fo buf count
541 if (rc < 0) then constructErrorAndFail "commitBuffer"
544 else do memcpy (plusAddr fo_buf (AddrOff# new_wptr)) buf count
545 setBufWPtr fo (new_wptr + count)
548 write_buf fo buf 0 = return 0
549 write_buf fo buf count = do
550 rc <- mayBlock fo (write_ fo buf count)
552 then write_buf fo buf (count - rc) -- partial write
555 -- a version of commitBuffer that will free the buffer if an exception is
556 -- received. DON'T use this if you intend to use the buffer again!
557 checkedCommitBuffer handle buf sz count flush
558 = catchException (commitBuffer handle buf sz count flush)
559 (\e -> do withHandle__ handle (\h_ -> freeBuffer h_ buf sz)
562 foreign import "memcpy" unsafe memcpy :: Addr -> Addr -> Int -> IO ()
565 Going across the border between Haskell and C is relatively costly,
566 so for block writes we pack the character strings on the Haskell-side
567 before passing the external write routine a pointer to the buffer.
572 #ifdef __CONCURRENT_HASKELL__
573 /* See comment in shoveString below for explanation */
574 #warning delayed update of buffer disnae work with killThread
577 writeLines :: Handle -> Addr -> Int -> String -> IO ()
578 writeLines handle buf bufLen s =
580 shoveString :: Int -> [Char] -> IO ()
583 [] -> commitAndReleaseBuffer handle buf buflen n False{-no need to flush-}
586 primWriteCharOffAddr buf n x
587 {- Flushing on buffer exhaustion or newlines (even if it isn't the last one) -}
589 if next_n == bufLen || x == '\n'
591 checkedCommitBuffer hdl buf len next_n True{-needs flush-}
594 shoveString next_n xs
598 #else /* ndef __HUGS__ */
600 writeLines :: Handle -> Addr -> Int -> String -> IO ()
601 writeLines hdl buf len@(I# bufLen) s =
603 shoveString :: Int# -> [Char] -> IO ()
606 [] -> commitAndReleaseBuffer hdl buf len (I# n) False{-no need to flush-}
610 -- Flushing on buffer exhaustion or newlines
611 -- (even if it isn't the last one)
613 if next_n ==# bufLen || x `eqChar#` '\n'#
615 checkedCommitBuffer hdl buf len (I# next_n) True{-needs flush-}
618 shoveString next_n xs
621 #endif /* ndef __HUGS__ */
624 writeBlocks :: Handle -> Addr -> Int -> String -> IO ()
625 writeBlocks hdl buf bufLen s =
627 shoveString :: Int -> [Char] -> IO ()
630 [] -> commitAndReleaseBuffer hdl buf len n False{-no need to flush-}
633 primWriteCharOffAddr buf n x
637 checkedCommitBuffer hdl buf len next_n True{-needs flush-}
640 shoveString next_n xs
644 #else /* ndef __HUGS__ */
646 writeBlocks :: Handle -> Addr -> Int -> String -> IO ()
647 writeBlocks hdl buf len@(I# bufLen) s =
649 shoveString :: Int# -> [Char] -> IO ()
652 [] -> commitAndReleaseBuffer hdl buf len (I# n) False{-no need to flush-}
659 checkedCommitBuffer hdl buf len (I# next_n) True{-needs flush-}
662 shoveString next_n xs
666 write_char :: Addr -> Int# -> Char# -> IO ()
667 write_char (A# buf#) n# c# =
669 case (writeCharOffAddr# buf# n# c# s#) of s2# -> (# s2#, () #)
670 #endif /* ndef __HUGS__ */
673 Computation @hPrint hdl t@ writes the string representation of {\em t}
674 given by the @shows@ function to the file or channel managed by {\em
677 [ Seem to have disappeared from the 1.4 interface - SOF 2/97 ]
680 hPrint :: Show a => Handle -> a -> IO ()
681 hPrint hdl = hPutStrLn hdl . show
684 Derived action @hPutStrLn hdl str@ writes the string \tr{str} to
685 the handle \tr{hdl}, adding a newline at the end.
688 hPutStrLn :: Handle -> String -> IO ()
689 hPutStrLn hndl str = do