1 {-# OPTIONS -fno-implicit-prelude #-}
5 -- -----------------------------------------------------------------------------
6 -- $Id: PrelIO.hsc,v 1.9 2001/08/05 00:24:10 ken Exp $
8 -- (c) The University of Glasgow, 1992-2001
12 -- This module defines all basic IO operations.
13 -- These are needed for the IO operations exported by Prelude,
14 -- but as it happens they also do everything required by library
20 #include "PrelHandle_hsc.h"
26 import PrelMarshalAlloc
27 import PrelMarshalUtils
35 import PrelHandle -- much of the real stuff is in here
42 import PrelMaybe ( Maybe(..) )
45 import PrelException ( ioError, catch, throw )
48 -- -----------------------------------------------------------------------------
51 putChar :: Char -> IO ()
52 putChar c = hPutChar stdout c
54 putStr :: String -> IO ()
55 putStr s = hPutStr stdout s
57 putStrLn :: String -> IO ()
58 putStrLn s = do putStr s
61 print :: Show a => a -> IO ()
62 print x = putStrLn (show x)
65 getChar = hGetChar stdin
68 getLine = hGetLine stdin
70 getContents :: IO String
71 getContents = hGetContents stdin
73 interact :: (String -> String) -> IO ()
74 interact f = do s <- getContents
77 readFile :: FilePath -> IO String
78 readFile name = openFile name ReadMode >>= hGetContents
80 writeFile :: FilePath -> String -> IO ()
81 writeFile name str = do
82 hdl <- openFile name WriteMode
86 appendFile :: FilePath -> String -> IO ()
87 appendFile name str = do
88 hdl <- openFile name AppendMode
92 readLn :: Read a => IO a
93 readLn = do l <- getLine
97 -- raises an exception instead of an error
98 readIO :: Read a => String -> IO a
99 readIO s = case (do { (x,t) <- reads s ;
102 #ifndef NEW_READS_REP
104 [] -> ioError (userError "Prelude.readIO: no parse")
105 _ -> ioError (userError "Prelude.readIO: ambiguous parse")
108 Nothing -> ioError (userError "Prelude.readIO: no parse")
111 -- ---------------------------------------------------------------------------
112 -- Simple input operations
114 -- Computation "hReady hdl" indicates whether at least
115 -- one item is available for input from handle "hdl".
117 -- If hWaitForInput finds anything in the Handle's buffer, it
118 -- immediately returns. If not, it tries to read from the underlying
119 -- OS handle. Notice that for buffered Handles connected to terminals
120 -- this means waiting until a complete line is available.
122 hReady :: Handle -> IO Bool
123 hReady h = hWaitForInput h 0
125 hWaitForInput :: Handle -> Int -> IO Bool
126 hWaitForInput h msecs = do
127 wantReadableHandle "hReady" h $ \ handle_ -> do
128 let ref = haBuffer handle_
131 if not (bufferEmpty buf)
135 r <- throwErrnoIfMinus1Retry "hReady"
136 (inputReady (fromIntegral (haFD handle_)) (fromIntegral msecs))
139 foreign import "inputReady"
140 inputReady :: CInt -> CInt -> IO CInt
142 -- ---------------------------------------------------------------------------
145 -- hGetChar reads the next character from a handle,
146 -- blocking until a character is available.
148 hGetChar :: Handle -> IO Char
150 wantReadableHandle "hGetChar" handle $ \handle_ -> do
152 let fd = haFD handle_
153 ref = haBuffer handle_
156 if not (bufferEmpty buf)
157 then hGetcBuffered fd ref buf
161 case haBufferMode handle_ of
163 new_buf <- fillReadBuffer fd True buf
164 hGetcBuffered fd ref new_buf
165 BlockBuffering _ -> do
166 new_buf <- fillReadBuffer fd False buf
167 hGetcBuffered fd ref new_buf
169 -- make use of the minimal buffer we already have
171 r <- throwErrnoIfMinus1RetryMayBlock "hGetChar"
172 (read_off (fromIntegral fd) raw 0 1)
176 else do (c,_) <- readCharFromBuffer raw 0
179 hGetcBuffered fd ref buf@Buffer{ bufBuf=b, bufRPtr=r, bufWPtr=w }
180 = do (c,r) <- readCharFromBuffer b r
181 let new_buf | r == w = buf{ bufRPtr=0, bufWPtr=0 }
182 | otherwise = buf{ bufRPtr=r }
183 writeIORef ref new_buf
186 -- ---------------------------------------------------------------------------
189 -- If EOF is reached before EOL is encountered, ignore the EOF and
190 -- return the partial line. Next attempt at calling hGetLine on the
191 -- handle will yield an EOF IO exception though.
193 -- ToDo: the unbuffered case is wrong: it doesn't lock the handle for
195 hGetLine :: Handle -> IO String
197 m <- wantReadableHandle "hGetLine" h $ \ handle_ -> do
198 case haBufferMode handle_ of
199 NoBuffering -> return Nothing
201 l <- hGetLineBuffered handle_
203 BlockBuffering _ -> do
204 l <- hGetLineBuffered handle_
207 Nothing -> hGetLineUnBuffered h
211 hGetLineBuffered handle_ = do
212 let ref = haBuffer handle_
214 hGetLineBufferedLoop handle_ ref buf []
217 hGetLineBufferedLoop handle_ ref
218 buf@Buffer{ bufRPtr=r, bufWPtr=w, bufBuf=raw } xss =
220 -- find the end-of-line character, if there is one
222 | r == w = return (False, w)
224 (c,r') <- readCharFromBuffer raw r
226 then return (True, r) -- NB. not r': don't include the '\n'
229 (eol, off) <- loop raw r
232 puts ("hGetLineBufferedLoop: r=" ++ show r ++ ", w=" ++ show w ++ ", off=" ++ show off ++ "\n")
235 xs <- unpack raw r off
237 then do if w == off + 1
238 then writeIORef ref buf{ bufRPtr=0, bufWPtr=0 }
239 else writeIORef ref buf{ bufRPtr = off + 1 }
240 return (concat (reverse (xs:xss)))
242 maybe_buf <- maybeFillReadBuffer (haFD handle_) True
243 buf{ bufWPtr=0, bufRPtr=0 }
245 -- Nothing indicates we caught an EOF, and we may have a
246 -- partial line to return.
247 Nothing -> let str = concat (reverse (xs:xss)) in
252 hGetLineBufferedLoop handle_ ref new_buf (xs:xss)
255 maybeFillReadBuffer fd is_line buf
257 (do buf <- fillReadBuffer fd is_line buf
260 (\e -> do if isEOFError e
265 unpack :: RawBuffer -> Int -> Int -> IO [Char]
266 unpack buf r 0 = return ""
267 unpack buf (I## r) (I## len) = IO $ \s -> unpack [] (len -## 1##) s
270 | i <## r = (## s, acc ##)
272 case readCharArray## buf i s of
273 (## s, ch ##) -> unpack (C## ch : acc) (i -## 1##) s
276 hGetLineUnBuffered :: Handle -> IO String
277 hGetLineUnBuffered h = do
290 if isEOFError err then
300 -- -----------------------------------------------------------------------------
303 -- hGetContents returns the list of characters corresponding to the
304 -- unread portion of the channel or file managed by the handle, which
305 -- is made semi-closed.
307 -- hGetContents on a DuplexHandle only affects the read side: you can
308 -- carry on writing to it afterwards.
310 hGetContents :: Handle -> IO String
311 hGetContents handle =
312 withHandle "hGetContents" handle $ \handle_ ->
313 case haType handle_ of
314 ClosedHandle -> ioe_closedHandle
315 SemiClosedHandle -> ioe_closedHandle
316 AppendHandle -> ioe_notReadable
317 WriteHandle -> ioe_notReadable
318 _ -> do xs <- lazyRead handle
319 return (handle_{ haType=SemiClosedHandle}, xs )
321 -- Note that someone may close the semi-closed handle (or change its
322 -- buffering), so each time these lazy read functions are pulled on,
323 -- they have to check whether the handle has indeed been closed.
325 lazyRead :: Handle -> IO String
328 withHandle "lazyRead" handle $ \ handle_ -> do
329 case haType handle_ of
330 ClosedHandle -> return (handle_, "")
331 SemiClosedHandle -> lazyRead' handle handle_
333 (IOError (Just handle) IllegalOperation "lazyRead"
334 "illegal handle type" Nothing)
336 lazyRead' h handle_ = do
337 let ref = haBuffer handle_
340 -- even a NoBuffering handle can have a char in the buffer...
343 if not (bufferEmpty buf)
344 then lazyReadHaveBuffer h handle_ fd ref buf
347 case haBufferMode handle_ of
349 -- make use of the minimal buffer we already have
352 r <- throwErrnoIfMinus1RetryMayBlock "lazyRead"
353 (read_off (fromIntegral fd) raw 0 1)
356 then do handle_ <- hClose_help handle_
358 else do (c,_) <- readCharFromBuffer raw 0
360 return (handle_, c : rest)
362 LineBuffering -> lazyReadBuffered h handle_ fd ref buf
363 BlockBuffering _ -> lazyReadBuffered h handle_ fd ref buf
365 -- we never want to block during the read, so we call fillReadBuffer with
366 -- is_line==True, which tells it to "just read what there is".
367 lazyReadBuffered h handle_ fd ref buf = do
369 (do buf <- fillReadBuffer fd True{-is_line-} buf
370 lazyReadHaveBuffer h handle_ fd ref buf
372 -- all I/O errors are discarded. Additionally, we close the handle.
373 (\e -> do handle_ <- hClose_help handle_
377 lazyReadHaveBuffer h handle_ fd ref buf = do
379 writeIORef ref buf{ bufRPtr=0, bufWPtr=0 }
380 s <- unpackAcc (bufBuf buf) (bufRPtr buf) (bufWPtr buf) more
384 unpackAcc :: RawBuffer -> Int -> Int -> [Char] -> IO [Char]
385 unpackAcc buf r 0 acc = return ""
386 unpackAcc buf (I## r) (I## len) acc = IO $ \s -> unpack acc (len -## 1##) s
389 | i <## r = (## s, acc ##)
391 case readCharArray## buf i s of
392 (## s, ch ##) -> unpack (C## ch : acc) (i -## 1##) s
394 -- ---------------------------------------------------------------------------
397 -- `hPutChar hdl ch' writes the character `ch' to the file or channel
398 -- managed by `hdl'. Characters may be buffered if buffering is
399 -- enabled for `hdl'.
401 hPutChar :: Handle -> Char -> IO ()
403 c `seq` do -- must evaluate c before grabbing the handle lock
404 wantWritableHandle "hPutChar" handle $ \ handle_ -> do
405 let fd = haFD handle_
406 case haBufferMode handle_ of
407 LineBuffering -> hPutcBuffered handle_ True c
408 BlockBuffering _ -> hPutcBuffered handle_ False c
410 withObject (castCharToCChar c) $ \buf ->
411 throwErrnoIfMinus1RetryMayBlock_ "hPutChar"
412 (c_write (fromIntegral fd) buf 1)
416 hPutcBuffered handle_ is_line c = do
417 let ref = haBuffer handle_
420 w' <- writeCharIntoBuffer (bufBuf buf) w c
421 let new_buf = buf{ bufWPtr = w' }
422 if bufferFull new_buf || is_line && c == '\n'
424 flushed_buf <- flushWriteBuffer (haFD handle_) new_buf
425 writeIORef ref flushed_buf
427 writeIORef ref new_buf
430 hPutChars :: Handle -> [Char] -> IO ()
431 hPutChars handle [] = return ()
432 hPutChars handle (c:cs) = hPutChar handle c >> hPutChars handle cs
434 -- ---------------------------------------------------------------------------
437 -- `hPutStr hdl s' writes the string `s' to the file or
438 -- hannel managed by `hdl', buffering the output if needs be.
440 -- We go to some trouble to avoid keeping the handle locked while we're
441 -- evaluating the string argument to hPutStr, in case doing so triggers another
442 -- I/O operation on the same handle which would lead to deadlock. The classic
445 -- putStr (trace "hello" "world")
447 -- so the basic scheme is this:
449 -- * copy the string into a fresh buffer,
450 -- * "commit" the buffer to the handle.
452 -- Committing may involve simply copying the contents of the new
453 -- buffer into the handle's buffer, flushing one or both buffers, or
454 -- maybe just swapping the buffers over (if the handle's buffer was
455 -- empty). See commitBuffer below.
457 hPutStr :: Handle -> String -> IO ()
458 hPutStr handle str = do
459 buffer_mode <- wantWritableHandle "hPutStr" handle
460 (\ handle_ -> do getSpareBuffer handle_)
462 (NoBuffering, _) -> do
463 hPutChars handle str -- v. slow, but we don't care
464 (LineBuffering, buf) -> do
465 writeLines handle buf str
466 (BlockBuffering _, buf) -> do
467 writeBlocks handle buf str
470 getSpareBuffer :: Handle__ -> IO (BufferMode, Buffer)
471 getSpareBuffer Handle__{haBuffer=ref,
476 NoBuffering -> return (mode, error "no buffer!")
478 bufs <- readIORef spare_ref
481 BufferListCons b rest -> do
482 writeIORef spare_ref rest
483 return ( mode, newEmptyBuffer b WriteBuffer (bufSize buf))
485 new_buf <- allocateBuffer (bufSize buf) WriteBuffer
486 return (mode, new_buf)
489 writeLines :: Handle -> Buffer -> String -> IO ()
490 writeLines hdl Buffer{ bufBuf=raw, bufSize=len } s =
492 shoveString :: Int -> [Char] -> IO ()
493 -- check n == len first, to ensure that shoveString is strict in n.
494 shoveString n cs | n == len = do
495 new_buf <- commitBuffer hdl raw len n True{-needs flush-} False
496 writeBlocks hdl new_buf cs
497 shoveString n [] = do
498 commitBuffer hdl raw len n False{-no flush-} True{-release-}
500 shoveString n (c:cs) = do
501 n' <- writeCharIntoBuffer raw n c
506 writeBlocks :: Handle -> Buffer -> String -> IO ()
507 writeBlocks hdl Buffer{ bufBuf=raw, bufSize=len } s =
509 shoveString :: Int -> [Char] -> IO ()
510 -- check n == len first, to ensure that shoveString is strict in n.
511 shoveString n cs | n == len = do
512 new_buf <- commitBuffer hdl raw len n True{-needs flush-} False
513 writeBlocks hdl new_buf cs
514 shoveString n [] = do
515 commitBuffer hdl raw len n False{-no flush-} True{-release-}
517 shoveString n (c:cs) = do
518 n' <- writeCharIntoBuffer raw n c
523 -- -----------------------------------------------------------------------------
524 -- commitBuffer handle buf sz count flush release
526 -- Write the contents of the buffer 'buf' ('sz' bytes long, containing
527 -- 'count' bytes of data) to handle (handle must be block or line buffered).
531 -- for block/line buffering,
532 -- 1. If there isn't room in the handle buffer, flush the handle
535 -- 2. If the handle buffer is empty,
537 -- then write buf directly to the device.
538 -- else swap the handle buffer with buf.
540 -- 3. If the handle buffer is non-empty, copy buf into the
541 -- handle buffer. Then, if flush != 0, flush
545 :: Handle -- handle to commit to
546 -> RawBuffer -> Int -- address and size (in bytes) of buffer
547 -> Int -- number of bytes of data in buffer
548 -> Bool -- flush the handle afterward?
549 -> Bool -- release the buffer?
552 commitBuffer hdl raw sz count flush release = do
553 wantWritableHandle "commitAndReleaseBuffer" hdl $
554 \ handle_@Handle__{ haFD=fd, haBuffer=ref, haBuffers=spare_buf_ref } -> do
557 puts ("commitBuffer: sz=" ++ show sz ++ ", count=" ++ show count
558 ++ ", flush=" ++ show flush ++ ", release=" ++ show release ++"\n")
561 old_buf@Buffer{ bufBuf=old_raw, bufRPtr=r, bufWPtr=w, bufSize=size }
565 -- enough room in handle buffer?
566 if (not flush && (size - w > count))
567 -- The > is to be sure that we never exactly fill
568 -- up the buffer, which would require a flush. So
569 -- if copying the new data into the buffer would
570 -- make the buffer full, we just flush the existing
571 -- buffer and the new data immediately, rather than
572 -- copying before flushing.
574 -- not flushing, and there's enough room in the buffer:
575 -- just copy the data in and update bufWPtr.
576 then do memcpy_off old_raw w raw (fromIntegral count)
577 writeIORef ref old_buf{ bufWPtr = w + count }
578 return (newEmptyBuffer raw WriteBuffer sz)
580 -- else, we have to flush
581 else do flushed_buf <- flushWriteBuffer fd old_buf
584 Buffer{ bufBuf=raw, bufState=WriteBuffer,
585 bufRPtr=0, bufWPtr=count, bufSize=sz }
587 -- if: (a) we don't have to flush, and
588 -- (b) size(new buffer) == size(old buffer), and
589 -- (c) new buffer is not full,
590 -- we can just just swap them over...
591 if (not flush && sz == size && count /= sz)
593 writeIORef ref this_buf
596 -- otherwise, we have to flush the new data too,
597 -- and start with a fresh buffer
599 flushWriteBuffer fd this_buf
600 writeIORef ref flushed_buf
601 -- if the sizes were different, then allocate
602 -- a new buffer of the correct size.
604 then return (newEmptyBuffer raw WriteBuffer sz)
605 else allocateBuffer size WriteBuffer
607 -- release the buffer if necessary
608 if release && bufSize buf_ret == size
610 spare_bufs <- readIORef spare_buf_ref
611 writeIORef spare_buf_ref
612 (BufferListCons (bufBuf buf_ret) spare_bufs)
618 foreign import "memcpy_wrap" unsafe
619 memcpy_off :: RawBuffer -> Int -> RawBuffer -> CSize -> IO (Ptr ())
621 void *memcpy_wrap(char *dst, HsInt dst_off, const char *src, size_t sz) \
622 { return memcpy(dst+dst_off, src, sz); }
624 -- ---------------------------------------------------------------------------
627 -- Derived action `hPutStrLn hdl str' writes the string `str' to
628 -- the handle `hdl', adding a newline at the end.
630 hPutStrLn :: Handle -> String -> IO ()
631 hPutStrLn hndl str = do
635 -- ---------------------------------------------------------------------------
638 -- Computation `hPrint hdl t' writes the string representation of `t'
639 -- given by the `shows' function to the file or channel managed by `hdl'.
641 hPrint :: Show a => Handle -> a -> IO ()
642 hPrint hdl = hPutStrLn hdl . show