1 {-# OPTIONS -fno-implicit-prelude #-}
5 -- -----------------------------------------------------------------------------
6 -- $Id: IO.hsc,v 1.1 2001/06/28 14:15:03 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 "GHC/Handle_hsc.h"
33 import GHC.Handle -- much of the real stuff is in here
38 import GHC.Exception ( ioError, catch, throw )
41 -- ---------------------------------------------------------------------------
42 -- Simple input operations
44 -- Computation "hReady hdl" indicates whether at least
45 -- one item is available for input from handle "hdl".
47 -- If hWaitForInput finds anything in the Handle's buffer, it
48 -- immediately returns. If not, it tries to read from the underlying
49 -- OS handle. Notice that for buffered Handles connected to terminals
50 -- this means waiting until a complete line is available.
52 hWaitForInput :: Handle -> Int -> IO Bool
53 hWaitForInput h msecs = do
54 wantReadableHandle "hReady" h $ \ handle_ -> do
55 let ref = haBuffer handle_
58 if not (bufferEmpty buf)
62 r <- throwErrnoIfMinus1Retry "hReady"
63 (inputReady (fromIntegral (haFD handle_)) (fromIntegral msecs))
66 foreign import "inputReady"
67 inputReady :: CInt -> CInt -> IO CInt
69 -- ---------------------------------------------------------------------------
72 -- hGetChar reads the next character from a handle,
73 -- blocking until a character is available.
75 hGetChar :: Handle -> IO Char
77 wantReadableHandle "hGetChar" handle $ \handle_ -> do
80 ref = haBuffer handle_
83 if not (bufferEmpty buf)
84 then hGetcBuffered fd ref buf
88 case haBufferMode handle_ of
90 new_buf <- fillReadBuffer fd True buf
91 hGetcBuffered fd ref new_buf
92 BlockBuffering _ -> do
93 new_buf <- fillReadBuffer fd False buf
94 hGetcBuffered fd ref new_buf
96 -- make use of the minimal buffer we already have
98 r <- throwErrnoIfMinus1RetryMayBlock "hGetChar"
99 (read_off (fromIntegral fd) raw 0 1)
103 else do (c,_) <- readCharFromBuffer raw 0
106 hGetcBuffered fd ref buf@Buffer{ bufBuf=b, bufRPtr=r, bufWPtr=w }
107 = do (c,r) <- readCharFromBuffer b r
108 let new_buf | r == w = buf{ bufRPtr=0, bufWPtr=0 }
109 | otherwise = buf{ bufRPtr=r }
110 writeIORef ref new_buf
113 -- ---------------------------------------------------------------------------
116 -- If EOF is reached before EOL is encountered, ignore the EOF and
117 -- return the partial line. Next attempt at calling hGetLine on the
118 -- handle will yield an EOF IO exception though.
120 -- ToDo: the unbuffered case is wrong: it doesn't lock the handle for
122 hGetLine :: Handle -> IO String
124 m <- wantReadableHandle "hGetLine" h $ \ handle_ -> do
125 case haBufferMode handle_ of
126 NoBuffering -> return Nothing
128 l <- hGetLineBuffered handle_
130 BlockBuffering _ -> do
131 l <- hGetLineBuffered handle_
134 Nothing -> hGetLineUnBuffered h
138 hGetLineBuffered handle_ = do
139 let ref = haBuffer handle_
141 hGetLineBufferedLoop handle_ ref buf []
144 hGetLineBufferedLoop handle_ ref
145 buf@Buffer{ bufRPtr=r, bufWPtr=w, bufBuf=raw } xss =
147 -- find the end-of-line character, if there is one
149 | r == w = return (False, w)
151 (c,r') <- readCharFromBuffer raw r
153 then return (True, r) -- NB. not r': don't include the '\n'
156 (eol, off) <- loop raw r
159 puts ("hGetLineBufferedLoop: r=" ++ show r ++ ", w=" ++ show w ++ ", off=" ++ show off ++ "\n")
162 xs <- unpack raw r off
164 then do if w == off + 1
165 then writeIORef ref buf{ bufRPtr=0, bufWPtr=0 }
166 else writeIORef ref buf{ bufRPtr = off + 1 }
167 return (concat (reverse (xs:xss)))
169 maybe_buf <- maybeFillReadBuffer (haFD handle_) True
170 buf{ bufWPtr=0, bufRPtr=0 }
172 -- Nothing indicates we caught an EOF, and we may have a
173 -- partial line to return.
174 Nothing -> let str = concat (reverse (xs:xss)) in
179 hGetLineBufferedLoop handle_ ref new_buf (xs:xss)
182 unpack :: RawBuffer -> Int -> Int -> IO [Char]
183 unpack buf r 0 = return ""
184 unpack buf (I## r) (I## len) = IO $ \s -> unpack [] (len -## 1##) s
187 | i <## r = (## s, acc ##)
189 case readCharArray## buf i s of
190 (## s, ch ##) -> unpack (C## ch : acc) (i -## 1##) s
193 hGetLineUnBuffered :: Handle -> IO String
194 hGetLineUnBuffered h = do
207 if isEOFError err then
217 -- -----------------------------------------------------------------------------
220 -- hGetContents returns the list of characters corresponding to the
221 -- unread portion of the channel or file managed by the handle, which
222 -- is made semi-closed.
224 -- hGetContents on a DuplexHandle only affects the read side: you can
225 -- carry on writing to it afterwards.
227 hGetContents :: Handle -> IO String
228 hGetContents handle@(DuplexHandle r w)
229 = withHandle' "hGetContents" handle r (hGetContents' handle)
230 hGetContents handle@(FileHandle m)
231 = withHandle' "hGetContents" handle m (hGetContents' handle)
233 hGetContents' handle handle_ =
234 case haType handle_ of
235 ClosedHandle -> ioe_closedHandle
236 SemiClosedHandle -> ioe_closedHandle
237 AppendHandle -> ioe_notReadable
238 WriteHandle -> ioe_notReadable
239 _ -> do xs <- lazyRead handle
240 return (handle_{ haType=SemiClosedHandle}, xs )
242 -- Note that someone may close the semi-closed handle (or change its
243 -- buffering), so each time these lazy read functions are pulled on,
244 -- they have to check whether the handle has indeed been closed.
246 lazyRead :: Handle -> IO String
249 withHandle_ "lazyRead" handle $ \ handle_ -> do
250 case haType handle_ of
251 ClosedHandle -> return ""
252 SemiClosedHandle -> lazyRead' handle handle_
254 (IOError (Just handle) IllegalOperation "lazyRead"
255 "illegal handle type" Nothing)
257 lazyRead' h handle_ = do
258 let ref = haBuffer handle_
261 -- even a NoBuffering handle can have a char in the buffer...
264 if not (bufferEmpty buf)
265 then lazyReadBuffered h fd ref buf
268 case haBufferMode handle_ of
270 -- make use of the minimal buffer we already have
273 r <- throwErrnoIfMinus1RetryMayBlock "hGetChar"
274 (read_off (fromIntegral fd) raw 0 1)
278 else do (c,_) <- readCharFromBuffer raw 0
282 LineBuffering -> lazyReadBuffered h fd ref buf
283 BlockBuffering _ -> lazyReadBuffered h fd ref buf
285 -- we never want to block during the read, so we call fillReadBuffer with
286 -- is_line==True, which tells it to "just read what there is".
287 lazyReadBuffered h fd ref buf = do
290 then maybeFillReadBuffer fd True buf
291 else return (Just buf)
292 case maybe_new_buf of
296 writeIORef ref buf{ bufRPtr=0, bufWPtr=0 }
297 unpackAcc (bufBuf buf) (bufRPtr buf) (bufWPtr buf) more
300 maybeFillReadBuffer fd is_line buf
302 (do buf <- fillReadBuffer fd is_line buf
305 (\e -> if isEOFError e
310 unpackAcc :: RawBuffer -> Int -> Int -> [Char] -> IO [Char]
311 unpackAcc buf r 0 acc = return ""
312 unpackAcc buf (I## r) (I## len) acc = IO $ \s -> unpack acc (len -## 1##) s
315 | i <## r = (## s, acc ##)
317 case readCharArray## buf i s of
318 (## s, ch ##) -> unpack (C## ch : acc) (i -## 1##) s
320 -- ---------------------------------------------------------------------------
323 -- `hPutChar hdl ch' writes the character `ch' to the file or channel
324 -- managed by `hdl'. Characters may be buffered if buffering is
325 -- enabled for `hdl'.
327 hPutChar :: Handle -> Char -> IO ()
329 c `seq` do -- must evaluate c before grabbing the handle lock
330 wantWritableHandle "hPutChar" handle $ \ handle_ -> do
331 let fd = haFD handle_
332 case haBufferMode handle_ of
333 LineBuffering -> hPutcBuffered handle_ True c
334 BlockBuffering _ -> hPutcBuffered handle_ False c
336 withObject (castCharToCChar c) $ \buf ->
337 throwErrnoIfMinus1RetryMayBlock_ "hPutChar"
338 (c_write (fromIntegral fd) buf 1)
342 hPutcBuffered handle_ is_line c = do
343 let ref = haBuffer handle_
346 w' <- writeCharIntoBuffer (bufBuf buf) w c
347 let new_buf = buf{ bufWPtr = w' }
348 if bufferFull new_buf || is_line && c == '\n'
350 flushed_buf <- flushWriteBuffer (haFD handle_) new_buf
351 writeIORef ref flushed_buf
353 writeIORef ref new_buf
356 hPutChars :: Handle -> [Char] -> IO ()
357 hPutChars handle [] = return ()
358 hPutChars handle (c:cs) = hPutChar handle c >> hPutChars handle cs
360 -- ---------------------------------------------------------------------------
363 -- `hPutStr hdl s' writes the string `s' to the file or
364 -- hannel managed by `hdl', buffering the output if needs be.
366 -- We go to some trouble to avoid keeping the handle locked while we're
367 -- evaluating the string argument to hPutStr, in case doing so triggers another
368 -- I/O operation on the same handle which would lead to deadlock. The classic
371 -- putStr (trace "hello" "world")
373 -- so the basic scheme is this:
375 -- * copy the string into a fresh buffer,
376 -- * "commit" the buffer to the handle.
378 -- Committing may involve simply copying the contents of the new
379 -- buffer into the handle's buffer, flushing one or both buffers, or
380 -- maybe just swapping the buffers over (if the handle's buffer was
381 -- empty). See commitBuffer below.
383 hPutStr :: Handle -> String -> IO ()
384 hPutStr handle str = do
385 buffer_mode <- wantWritableHandle "hPutStr" handle
386 (\ handle_ -> do getSpareBuffer handle_)
388 (NoBuffering, _) -> do
389 hPutChars handle str -- v. slow, but we don't care
390 (LineBuffering, buf) -> do
391 writeLines handle buf str
392 (BlockBuffering _, buf) -> do
393 writeBlocks handle buf str
396 getSpareBuffer :: Handle__ -> IO (BufferMode, Buffer)
397 getSpareBuffer Handle__{haBuffer=ref,
402 NoBuffering -> return (mode, error "no buffer!")
404 bufs <- readIORef spare_ref
407 BufferListCons b rest -> do
408 writeIORef spare_ref rest
409 return ( mode, newEmptyBuffer b WriteBuffer (bufSize buf))
411 new_buf <- allocateBuffer (bufSize buf) WriteBuffer
412 return (mode, new_buf)
415 writeLines :: Handle -> Buffer -> String -> IO ()
416 writeLines hdl Buffer{ bufBuf=raw, bufSize=len } s =
418 shoveString :: Int -> [Char] -> IO ()
419 -- check n == len first, to ensure that shoveString is strict in n.
420 shoveString n cs | n == len = do
421 new_buf <- commitBuffer hdl raw len n True{-needs flush-} False
422 writeBlocks hdl new_buf cs
423 shoveString n [] = do
424 commitBuffer hdl raw len n False{-no flush-} True{-release-}
426 shoveString n (c:cs) = do
427 n' <- writeCharIntoBuffer raw n c
432 writeBlocks :: Handle -> Buffer -> String -> IO ()
433 writeBlocks hdl Buffer{ bufBuf=raw, bufSize=len } s =
435 shoveString :: Int -> [Char] -> IO ()
436 -- check n == len first, to ensure that shoveString is strict in n.
437 shoveString n cs | n == len = do
438 new_buf <- commitBuffer hdl raw len n True{-needs flush-} False
439 writeBlocks hdl new_buf cs
440 shoveString n [] = do
441 commitBuffer hdl raw len n False{-no flush-} True{-release-}
443 shoveString n (c:cs) = do
444 n' <- writeCharIntoBuffer raw n c
449 -- -----------------------------------------------------------------------------
450 -- commitBuffer handle buf sz count flush release
452 -- Write the contents of the buffer 'buf' ('sz' bytes long, containing
453 -- 'count' bytes of data) to handle (handle must be block or line buffered).
457 -- for block/line buffering,
458 -- 1. If there isn't room in the handle buffer, flush the handle
461 -- 2. If the handle buffer is empty,
463 -- then write buf directly to the device.
464 -- else swap the handle buffer with buf.
466 -- 3. If the handle buffer is non-empty, copy buf into the
467 -- handle buffer. Then, if flush != 0, flush
471 :: Handle -- handle to commit to
472 -> RawBuffer -> Int -- address and size (in bytes) of buffer
473 -> Int -- number of bytes of data in buffer
474 -> Bool -- flush the handle afterward?
475 -> Bool -- release the buffer?
478 commitBuffer hdl raw sz count flush release = do
479 wantWritableHandle "commitAndReleaseBuffer" hdl $
480 \ handle_@Handle__{ haFD=fd, haBuffer=ref, haBuffers=spare_buf_ref } -> do
483 puts ("commitBuffer: sz=" ++ show sz ++ ", count=" ++ show count
484 ++ ", flush=" ++ show flush ++ ", release=" ++ show release ++"\n")
487 old_buf@Buffer{ bufBuf=old_raw, bufRPtr=r, bufWPtr=w, bufSize=size }
491 -- enough room in handle buffer?
492 if (not flush && (size - w > count))
493 -- The > is to be sure that we never exactly fill
494 -- up the buffer, which would require a flush. So
495 -- if copying the new data into the buffer would
496 -- make the buffer full, we just flush the existing
497 -- buffer and the new data immediately, rather than
498 -- copying before flushing.
500 -- not flushing, and there's enough room in the buffer:
501 -- just copy the data in and update bufWPtr.
502 then do memcpy_baoff_ba old_raw w raw (fromIntegral count)
503 writeIORef ref old_buf{ bufWPtr = w + count }
504 return (newEmptyBuffer raw WriteBuffer sz)
506 -- else, we have to flush
507 else do flushed_buf <- flushWriteBuffer fd old_buf
510 Buffer{ bufBuf=raw, bufState=WriteBuffer,
511 bufRPtr=0, bufWPtr=count, bufSize=sz }
513 -- if: (a) we don't have to flush, and
514 -- (b) size(new buffer) == size(old buffer), and
515 -- (c) new buffer is not full,
516 -- we can just just swap them over...
517 if (not flush && sz == size && count /= sz)
519 writeIORef ref this_buf
522 -- otherwise, we have to flush the new data too,
523 -- and start with a fresh buffer
525 flushWriteBuffer fd this_buf
526 writeIORef ref flushed_buf
527 -- if the sizes were different, then allocate
528 -- a new buffer of the correct size.
530 then return (newEmptyBuffer raw WriteBuffer sz)
531 else allocateBuffer size WriteBuffer
533 -- release the buffer if necessary
534 if release && bufSize buf_ret == size
536 spare_bufs <- readIORef spare_buf_ref
537 writeIORef spare_buf_ref
538 (BufferListCons (bufBuf buf_ret) spare_bufs)
543 -- ---------------------------------------------------------------------------
544 -- Reading/writing sequences of bytes.
547 Semantics of hGetBuf:
549 - hGetBuf reads data into the buffer until either
552 (b) the buffer is full
554 It returns the amount of data actually read. This may
555 be zero in case (a). hGetBuf never raises
556 an EOF exception, it always returns zero instead.
558 If the handle is a pipe or socket, and the writing end
559 is closed, hGetBuf will behave as for condition (a).
561 Semantics of hPutBuf:
563 - hPutBuf writes data from the buffer to the handle
564 until the buffer is empty. It returns ().
566 If the handle is a pipe or socket, and the reading end is
567 closed, hPutBuf will raise a ResourceVanished exception.
568 (If this is a POSIX system, and the program has not
569 asked to ignore SIGPIPE, then a SIGPIPE may be delivered
570 instead, whose default action is to terminate the program).
573 -- ---------------------------------------------------------------------------
576 hPutBuf :: Handle -- handle to write to
577 -> Ptr a -- address of buffer
578 -> Int -- number of bytes of data in buffer
580 hPutBuf handle ptr count
581 | count <= 0 = illegalBufferSize handle "hPutBuf" count
583 wantWritableHandle "hPutBuf" handle $
584 \ handle_@Handle__{ haFD=fd, haBuffer=ref } -> do
586 old_buf@Buffer{ bufBuf=old_raw, bufRPtr=r, bufWPtr=w, bufSize=size }
589 -- enough room in handle buffer?
590 if (size - w > count)
591 -- There's enough room in the buffer:
592 -- just copy the data in and update bufWPtr.
593 then do memcpy_baoff_ptr old_raw w ptr (fromIntegral count)
594 writeIORef ref old_buf{ bufWPtr = w + count }
597 -- else, we have to flush
598 else do flushed_buf <- flushWriteBuffer fd old_buf
599 writeIORef ref flushed_buf
600 -- ToDo: should just memcpy instead of writing if possible
601 writeChunk fd ptr count
603 writeChunk :: FD -> Ptr a -> Int -> IO ()
604 writeChunk fd ptr bytes = loop 0 bytes
606 loop :: Int -> Int -> IO ()
607 loop _ bytes | bytes <= 0 = return ()
609 r <- fromIntegral `liftM`
610 throwErrnoIfMinus1RetryMayBlock "writeChunk"
611 (c_write (fromIntegral fd) (ptr `plusPtr` off) (fromIntegral bytes))
613 -- write can't return 0
614 loop (off + r) (bytes - r)
616 -- ---------------------------------------------------------------------------
619 hGetBuf :: Handle -> Ptr a -> Int -> IO Int
620 hGetBuf handle ptr count
621 | count <= 0 = illegalBufferSize handle "hGetBuf" count
623 wantReadableHandle "hGetBuf" handle $
624 \ handle_@Handle__{ haFD=fd, haBuffer=ref } -> do
625 buf@Buffer{ bufBuf=raw, bufWPtr=w, bufRPtr=r } <- readIORef ref
627 then readChunk fd ptr count
630 copied <- if (count >= avail)
632 memcpy_ptr_baoff ptr raw r (fromIntegral avail)
633 writeIORef ref buf{ bufWPtr=0, bufRPtr=0 }
636 memcpy_ptr_baoff ptr raw r (fromIntegral count)
637 writeIORef ref buf{ bufRPtr = r + count }
640 let remaining = count - copied
642 then do rest <- readChunk fd (ptr `plusPtr` copied) remaining
643 return (rest + count)
646 readChunk :: FD -> Ptr a -> Int -> IO Int
647 readChunk fd ptr bytes = loop 0 bytes
649 loop :: Int -> Int -> IO Int
650 loop off bytes | bytes <= 0 = return off
652 r <- fromIntegral `liftM`
653 throwErrnoIfMinus1RetryMayBlock "readChunk"
654 (c_read (fromIntegral fd) (ptr `plusPtr` off) (fromIntegral bytes))
658 else loop (off + r) (bytes - r)
660 slurpFile :: FilePath -> IO (Ptr (), Int)
662 handle <- openFile fname ReadMode
663 sz <- hFileSize handle
664 if sz > fromIntegral (maxBound::Int) then
665 ioError (userError "slurpFile: file too big")
667 let sz_i = fromIntegral sz
668 chunk <- mallocBytes sz_i
669 r <- hGetBuf handle chunk sz_i
673 -- ---------------------------------------------------------------------------
676 hGetBufBA :: Handle -> MutableByteArray RealWorld a -> Int -> IO Int
677 hGetBufBA handle (MutableByteArray _ _ ptr) count
678 | count <= 0 = illegalBufferSize handle "hGetBuf" count
680 wantReadableHandle "hGetBuf" handle $
681 \ handle_@Handle__{ haFD=fd, haBuffer=ref } -> do
682 buf@Buffer{ bufBuf=raw, bufWPtr=w, bufRPtr=r } <- readIORef ref
684 then readChunkBA fd ptr 0 count
687 copied <- if (count >= avail)
689 memcpy_ba_baoff ptr raw r (fromIntegral avail)
690 writeIORef ref buf{ bufWPtr=0, bufRPtr=0 }
693 memcpy_ba_baoff ptr raw r (fromIntegral count)
694 writeIORef ref buf{ bufRPtr = r + count }
697 let remaining = count - copied
699 then do rest <- readChunkBA fd ptr copied remaining
700 return (rest + count)
703 readChunkBA :: FD -> RawBuffer -> Int -> Int -> IO Int
704 readChunkBA fd ptr init_off bytes = loop init_off bytes
706 loop :: Int -> Int -> IO Int
707 loop off bytes | bytes <= 0 = return (off - init_off)
709 r <- fromIntegral `liftM`
710 throwErrnoIfMinus1RetryMayBlock "readChunk"
711 (readBA (fromIntegral fd) ptr
712 (fromIntegral off) (fromIntegral bytes))
715 then return (off - init_off)
716 else loop (off + r) (bytes - r)
718 foreign import "read_ba_wrap" unsafe
719 readBA :: FD -> RawBuffer -> Int -> CInt -> IO CInt
721 int read_ba_wrap(int fd, void *ptr, HsInt off, int size) \
722 { return read(fd, ptr + off, size); }
724 -- -----------------------------------------------------------------------------
728 :: Handle -- handle to write to
729 -> MutableByteArray RealWorld a -- buffer
730 -> Int -- number of bytes of data in buffer
733 hPutBufBA handle (MutableByteArray _ _ raw) count
734 | count <= 0 = illegalBufferSize handle "hPutBufBA" count
736 wantWritableHandle "hPutBufBA" handle $
737 \ handle_@Handle__{ haFD=fd, haBuffer=ref } -> do
739 old_buf@Buffer{ bufBuf=old_raw, bufRPtr=r, bufWPtr=w, bufSize=size }
742 -- enough room in handle buffer?
743 if (size - w > count)
744 -- There's enough room in the buffer:
745 -- just copy the data in and update bufWPtr.
746 then do memcpy_baoff_ba old_raw w raw (fromIntegral count)
747 writeIORef ref old_buf{ bufWPtr = w + count }
750 -- else, we have to flush
751 else do flushed_buf <- flushWriteBuffer fd old_buf
752 writeIORef ref flushed_buf
754 Buffer{ bufBuf=raw, bufState=WriteBuffer,
755 bufRPtr=0, bufWPtr=count, bufSize=count }
756 flushWriteBuffer fd this_buf
759 -- ---------------------------------------------------------------------------
762 foreign import "memcpy_wrap_src_off" unsafe
763 memcpy_ba_baoff :: RawBuffer -> RawBuffer -> Int -> CSize -> IO (Ptr ())
764 foreign import "memcpy_wrap_src_off" unsafe
765 memcpy_ptr_baoff :: Ptr a -> RawBuffer -> Int -> CSize -> IO (Ptr ())
766 foreign import "memcpy_wrap_dst_off" unsafe
767 memcpy_baoff_ba :: RawBuffer -> Int -> RawBuffer -> CSize -> IO (Ptr ())
768 foreign import "memcpy_wrap_dst_off" unsafe
769 memcpy_baoff_ptr :: RawBuffer -> Int -> Ptr a -> CSize -> IO (Ptr ())
772 void *memcpy_wrap_dst_off(char *dst, int dst_off, char *src, size_t sz) \
773 { return memcpy(dst+dst_off, src, sz); }
776 void *memcpy_wrap_src_off(char *dst, char *src, int src_off, size_t sz) \
777 { return memcpy(dst, src+src_off, sz); }
779 -----------------------------------------------------------------------------
782 illegalBufferSize :: Handle -> String -> Int -> IO a
783 illegalBufferSize handle fn (sz :: Int) =
784 ioException (IOError (Just handle)
786 ("illegal buffer size " ++ showsPrec 9 sz [])