1 {-# OPTIONS -fno-implicit-prelude #-}
5 -- -----------------------------------------------------------------------------
6 -- $Id: PrelIO.hsc,v 1.1 2001/05/18 16:54:05 simonmar 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"
25 import PrelMarshalAlloc
26 import PrelMarshalUtils
34 import PrelHandle -- much of the real stuff is in here
39 import PrelRead ( Read(..), readIO )
41 import PrelMaybe ( Maybe(..) )
44 import PrelException ( ioError, catch, throw )
47 -- -----------------------------------------------------------------------------
50 putChar :: Char -> IO ()
51 putChar c = hPutChar stdout c
53 putStr :: String -> IO ()
54 putStr s = hPutStr stdout s
56 putStrLn :: String -> IO ()
57 putStrLn s = do putStr s
60 print :: Show a => a -> IO ()
61 print x = putStrLn (show x)
64 getChar = hGetChar stdin
67 getLine = hGetLine stdin
69 getContents :: IO String
70 getContents = hGetContents stdin
72 interact :: (String -> String) -> IO ()
73 interact f = do s <- getContents
76 readFile :: FilePath -> IO String
77 readFile name = openFile name ReadMode >>= hGetContents
79 writeFile :: FilePath -> String -> IO ()
80 writeFile name str = do
81 hdl <- openFile name WriteMode
85 appendFile :: FilePath -> String -> IO ()
86 appendFile name str = do
87 hdl <- openFile name AppendMode
91 readLn :: Read a => IO a
92 readLn = do l <- getLine
96 -- ---------------------------------------------------------------------------
97 -- Simple input operations
99 -- Computation "hReady hdl" indicates whether at least
100 -- one item is available for input from handle "hdl".
102 -- If hWaitForInput finds anything in the Handle's buffer, it
103 -- immediately returns. If not, it tries to read from the underlying
104 -- OS handle. Notice that for buffered Handles connected to terminals
105 -- this means waiting until a complete line is available.
107 hReady :: Handle -> IO Bool
108 hReady h = hWaitForInput h 0
110 hWaitForInput :: Handle -> Int -> IO Bool
111 hWaitForInput h msecs = do
112 wantReadableHandle "hReady" h $ \ handle_ -> do
113 let ref = haBuffer handle_
116 if not (bufferEmpty buf)
120 r <- throwErrnoIfMinus1Retry "hReady"
121 (inputReady (fromIntegral (haFD handle_)) (fromIntegral msecs))
124 foreign import "inputReady"
125 inputReady :: CInt -> CInt -> IO CInt
127 -- ---------------------------------------------------------------------------
130 -- hGetChar reads the next character from a handle,
131 -- blocking until a character is available.
133 hGetChar :: Handle -> IO Char
135 wantReadableHandle "hGetChar" handle $ \handle_ -> do
137 let fd = haFD handle_
138 ref = haBuffer handle_
141 if not (bufferEmpty buf)
142 then hGetcBuffered fd ref buf
146 case haBufferMode handle_ of
148 new_buf <- fillReadBuffer fd True buf
149 hGetcBuffered fd ref new_buf
150 BlockBuffering _ -> do
151 new_buf <- fillReadBuffer fd False buf
152 hGetcBuffered fd ref new_buf
154 -- make use of the minimal buffer we already have
156 r <- throwErrnoIfMinus1RetryMayBlock "hGetChar"
157 (read_off (fromIntegral fd) raw 0 1)
161 else do (c,_) <- readCharFromBuffer raw 0
164 hGetcBuffered fd ref buf@Buffer{ bufBuf=b, bufRPtr=r, bufWPtr=w }
165 = do (c,r) <- readCharFromBuffer b r
166 let new_buf | r == w = buf{ bufRPtr=0, bufWPtr=0 }
167 | otherwise = buf{ bufRPtr=r }
168 writeIORef ref new_buf
171 -- ---------------------------------------------------------------------------
174 -- If EOF is reached before EOL is encountered, ignore the EOF and
175 -- return the partial line. Next attempt at calling hGetLine on the
176 -- handle will yield an EOF IO exception though.
178 -- ToDo: the unbuffered case is wrong: it doesn't lock the handle for
180 hGetLine :: Handle -> IO String
182 m <- wantReadableHandle "hGetLine" h $ \ handle_ -> do
183 case haBufferMode handle_ of
184 NoBuffering -> return Nothing
186 l <- hGetLineBuffered handle_
188 BlockBuffering _ -> do
189 l <- hGetLineBuffered handle_
192 Nothing -> hGetLineUnBuffered h
196 hGetLineBuffered handle_ = do
197 let ref = haBuffer handle_
199 hGetLineBufferedLoop handle_ ref buf []
202 hGetLineBufferedLoop handle_ ref
203 buf@Buffer{ bufRPtr=r, bufWPtr=w, bufBuf=raw } xss =
205 -- find the end-of-line character, if there is one
207 | r == w = return (False, w)
209 (c,r') <- readCharFromBuffer raw r
211 then return (True, r) -- NB. not r': don't include the '\n'
214 (eol, off) <- loop raw r
217 puts ("hGetLineBufferedLoop: r=" ++ show r ++ ", w=" ++ show w ++ ", off=" ++ show off ++ "\n")
220 xs <- unpack raw r off
222 then do if w == off + 1
223 then writeIORef ref buf{ bufRPtr=0, bufWPtr=0 }
224 else writeIORef ref buf{ bufRPtr = off + 1 }
225 return (concat (reverse (xs:xss)))
227 maybe_buf <- maybeFillReadBuffer (haFD handle_) True
228 buf{ bufWPtr=0, bufRPtr=0 }
230 -- Nothing indicates we caught an EOF, and we may have a
231 -- partial line to return.
232 Nothing -> let str = concat (reverse (xs:xss)) in
237 hGetLineBufferedLoop handle_ ref new_buf (xs:xss)
240 unpack :: RawBuffer -> Int -> Int -> IO [Char]
241 unpack buf r 0 = return ""
242 unpack buf (I## r) (I## len) = IO $ \s -> unpack [] (len -## 1##) s
245 | i <## r = (## s, acc ##)
247 case readCharArray## buf i s of
248 (## s, ch ##) -> unpack (C## ch : acc) (i -## 1##) s
251 hGetLineUnBuffered :: Handle -> IO String
252 hGetLineUnBuffered h = do
265 if isEOFError err then
275 -- -----------------------------------------------------------------------------
278 -- hGetContents returns the list of characters corresponding to the
279 -- unread portion of the channel or file managed by the handle, which
280 -- is made semi-closed.
282 hGetContents :: Handle -> IO String
283 hGetContents handle =
284 -- can't use wantReadableHandle here, because we want to side effect
286 withHandle "hGetContents" handle $ \ handle_ -> do
287 case haType handle_ of
288 ClosedHandle -> ioe_closedHandle
289 SemiClosedHandle -> ioe_closedHandle
290 AppendHandle -> ioException not_readable_error
291 WriteHandle -> ioException not_readable_error
292 _ -> do xs <- lazyRead handle
293 return (handle_{ haType=SemiClosedHandle}, xs )
296 IOError (Just handle) IllegalOperation "hGetContents"
297 "handle is not open for reading" Nothing
299 -- Note that someone may close the semi-closed handle (or change its
300 -- buffering), so each these lazy read functions are pulled on, they
301 -- have to check whether the handle has indeed been closed.
303 lazyRead :: Handle -> IO String
306 withHandle_ "lazyRead" handle $ \ handle_ -> do
307 case haType handle_ of
308 ClosedHandle -> return ""
309 SemiClosedHandle -> lazyRead' handle handle_
311 (IOError (Just handle) IllegalOperation "lazyRead"
312 "illegal handle type" Nothing)
314 lazyRead' h handle_ = do
315 let ref = haBuffer handle_
318 -- even a NoBuffering handle can have a char in the buffer...
321 if not (bufferEmpty buf)
322 then lazyReadBuffered h fd ref buf
325 case haBufferMode handle_ of
327 -- make use of the minimal buffer we already have
330 r <- throwErrnoIfMinus1RetryMayBlock "hGetChar"
331 (read_off (fromIntegral fd) raw 0 1)
335 else do (c,_) <- readCharFromBuffer raw 0
339 LineBuffering -> lazyReadBuffered h fd ref buf
340 BlockBuffering _ -> lazyReadBuffered h fd ref buf
342 -- we never want to block during the read, so we call fillReadBuffer with
343 -- is_line==True, which tells it to "just read what there is".
344 lazyReadBuffered h fd ref buf = do
347 then maybeFillReadBuffer fd True buf
348 else return (Just buf)
349 case maybe_new_buf of
353 writeIORef ref buf{ bufRPtr=0, bufWPtr=0 }
354 unpackAcc (bufBuf buf) (bufRPtr buf) (bufWPtr buf) more
357 maybeFillReadBuffer fd is_line buf
359 (do buf <- fillReadBuffer fd is_line buf
362 (\e -> if isEOFError e
367 unpackAcc :: RawBuffer -> Int -> Int -> [Char] -> IO [Char]
368 unpackAcc buf r 0 acc = return ""
369 unpackAcc buf (I## r) (I## len) acc = IO $ \s -> unpack acc (len -## 1##) s
372 | i <## r = (## s, acc ##)
374 case readCharArray## buf i s of
375 (## s, ch ##) -> unpack (C## ch : acc) (i -## 1##) s
377 -- ---------------------------------------------------------------------------
380 -- `hPutChar hdl ch' writes the character `ch' to the file or channel
381 -- managed by `hdl'. Characters may be buffered if buffering is
382 -- enabled for `hdl'.
384 hPutChar :: Handle -> Char -> IO ()
386 c `seq` do -- must evaluate c before grabbing the handle lock
387 wantWritableHandle "hPutChar" handle $ \ handle_ -> do
388 let fd = haFD handle_
389 case haBufferMode handle_ of
390 LineBuffering -> hPutcBuffered handle_ True c
391 BlockBuffering _ -> hPutcBuffered handle_ False c
393 withObject (castCharToCChar c) $ \buf ->
394 throwErrnoIfMinus1RetryMayBlock_ "hPutChar"
395 (c_write (fromIntegral fd) buf 1)
399 hPutcBuffered handle_ is_line c = do
400 let ref = haBuffer handle_
403 w' <- writeCharIntoBuffer (bufBuf buf) w c
404 let new_buf = buf{ bufWPtr = w' }
405 if bufferFull new_buf || is_line && c == '\n'
407 flushed_buf <- flushWriteBuffer (haFD handle_) new_buf
408 writeIORef ref flushed_buf
410 writeIORef ref new_buf
413 hPutChars :: Handle -> [Char] -> IO ()
414 hPutChars handle [] = return ()
415 hPutChars handle (c:cs) = hPutChar handle c >> hPutChars handle cs
417 -- ---------------------------------------------------------------------------
420 -- `hPutStr hdl s' writes the string `s' to the file or
421 -- hannel managed by `hdl', buffering the output if needs be.
423 -- We go to some trouble to avoid keeping the handle locked while we're
424 -- evaluating the string argument to hPutStr, in case doing so triggers another
425 -- I/O operation on the same handle which would lead to deadlock. The classic
428 -- putStr (trace "hello" "world")
430 -- so the basic scheme is this:
432 -- * copy the string into a fresh buffer,
433 -- * "commit" the buffer to the handle.
435 -- Committing may involve simply copying the contents of the new
436 -- buffer into the handle's buffer, flushing one or both buffers, or
437 -- maybe just swapping the buffers over (if the handle's buffer was
438 -- empty). See commitBuffer below.
440 hPutStr :: Handle -> String -> IO ()
441 hPutStr handle str = do
442 buffer_mode <- wantWritableHandle "hPutStr" handle
443 (\ handle_ -> do getSpareBuffer handle_)
445 (NoBuffering, _) -> do
446 hPutChars handle str -- v. slow, but we don't care
447 (LineBuffering, buf) -> do
448 writeLines handle buf str
449 (BlockBuffering _, buf) -> do
450 writeBlocks handle buf str
453 getSpareBuffer :: Handle__ -> IO (BufferMode, Buffer)
454 getSpareBuffer handle_ = do
455 let mode = haBufferMode handle_
457 NoBuffering -> return (mode, error "no buffer!")
459 let spare_ref = haBuffers handle_
460 ref = haBuffer handle_
461 bufs <- readIORef spare_ref
464 BufferListCons b rest -> do
465 writeIORef spare_ref rest
466 return ( mode, newEmptyBuffer b WriteBuffer (bufSize buf))
468 new_buf <- allocateBuffer (bufSize buf) WriteBuffer
469 return (mode, new_buf)
472 writeLines :: Handle -> Buffer -> String -> IO ()
473 writeLines hdl Buffer{ bufBuf=raw, bufSize=len } s =
475 shoveString :: Int -> [Char] -> IO ()
476 -- check n == len first, to ensure that shoveString is strict in n.
477 shoveString n cs | n == len = do
478 new_buf <- commitBuffer hdl raw len n True{-needs flush-} False
479 writeBlocks hdl new_buf cs
480 shoveString n [] = do
481 commitBuffer hdl raw len n False{-no flush-} True{-release-}
483 shoveString n (c:cs) = do
484 n' <- writeCharIntoBuffer raw n c
489 writeBlocks :: Handle -> Buffer -> String -> IO ()
490 writeBlocks 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 -- -----------------------------------------------------------------------------
507 -- commitBuffer handle buf sz count flush release
509 -- Write the contents of the buffer 'buf' ('sz' bytes long, containing
510 -- 'count' bytes of data) to handle (handle must be block or line buffered).
514 -- for block/line buffering,
515 -- 1. If there isn't room in the handle buffer, flush the handle
518 -- 2. If the handle buffer is empty,
520 -- then write buf directly to the device.
521 -- else swap the handle buffer with buf.
523 -- 3. If the handle buffer is non-empty, copy buf into the
524 -- handle buffer. Then, if flush != 0, flush
528 :: Handle -- handle to commit to
529 -> RawBuffer -> Int -- address and size (in bytes) of buffer
530 -> Int -- number of bytes of data in buffer
531 -> Bool -- flush the handle afterward?
532 -> Bool -- release the buffer?
535 commitBuffer hdl raw sz count flush release = do
536 wantWritableHandle "commitAndReleaseBuffer" hdl $
537 \ handle_@Handle__{ haFD=fd, haBuffer=ref, haBuffers=spare_buf_ref } -> do
540 puts ("commitBuffer: sz=" ++ show sz ++ ", count=" ++ show count
541 ++ ", flush=" ++ show flush ++ ", release=" ++ show release ++"\n")
544 old_buf@Buffer{ bufBuf=old_raw, bufRPtr=r, bufWPtr=w, bufSize=size }
548 -- enough room in handle buffer?
549 if (not flush && (size - w > count))
550 -- The > is to be sure that we never exactly fill
551 -- up the buffer, which would require a flush. So
552 -- if copying the new data into the buffer would
553 -- make the buffer full, we just flush the existing
554 -- buffer and the new data immediately, rather than
555 -- copying before flushing.
557 -- not flushing, and there's enough room in the buffer:
558 -- just copy the data in and update bufWPtr.
559 then do memcpy_off old_raw w raw (fromIntegral count)
560 writeIORef ref old_buf{ bufWPtr = w + count }
561 return (newEmptyBuffer raw WriteBuffer sz)
563 -- else, we have to flush
564 else do flushed_buf <- flushWriteBuffer fd old_buf
567 Buffer{ bufBuf=raw, bufState=WriteBuffer,
568 bufRPtr=0, bufWPtr=count, bufSize=sz }
570 -- if: (a) we don't have to flush, and
571 -- (b) size(new buffer) == size(old buffer), and
572 -- (c) new buffer is not full,
573 -- we can just just swap them over...
574 if (not flush && sz == size && count /= sz)
576 writeIORef ref this_buf
579 -- otherwise, we have to flush the new data too,
580 -- and start with a fresh buffer
582 flushWriteBuffer fd this_buf
583 writeIORef ref flushed_buf
584 -- if the sizes were different, then allocate
585 -- a new buffer of the correct size.
587 then return (newEmptyBuffer raw WriteBuffer sz)
588 else allocateBuffer size WriteBuffer
590 -- release the buffer if necessary
591 if release && bufSize buf_ret == size
593 spare_bufs <- readIORef spare_buf_ref
594 writeIORef spare_buf_ref
595 (BufferListCons (bufBuf buf_ret) spare_bufs)
601 foreign import "memcpy_wrap" unsafe
602 memcpy_off :: RawBuffer -> Int -> RawBuffer -> CSize -> IO (Ptr ())
604 void *memcpy_wrap(char *dst, int dst_off, char *src, size_t sz) \
605 { return memcpy(dst+dst_off, src, sz); }
607 -- ---------------------------------------------------------------------------
610 -- Derived action `hPutStrLn hdl str' writes the string `str' to
611 -- the handle `hdl', adding a newline at the end.
613 hPutStrLn :: Handle -> String -> IO ()
614 hPutStrLn hndl str = do
618 -- ---------------------------------------------------------------------------
621 -- Computation `hPrint hdl t' writes the string representation of `t'
622 -- given by the `shows' function to the file or channel managed by `hdl'.
624 hPrint :: Show a => Handle -> a -> IO ()
625 hPrint hdl = hPutStrLn hdl . show