83813b101db84c83c4f1efae4da2617fc5970eb9
[ghc-hetmet.git] / ghc / lib / std / PrelIO.hsc
1 {-# OPTIONS -fno-implicit-prelude #-}
2
3 #undef DEBUG_DUMP
4
5 -- -----------------------------------------------------------------------------
6 -- $Id: PrelIO.hsc,v 1.9 2001/08/05 00:24:10 ken Exp $
7 --
8 -- (c) The University of Glasgow, 1992-2001
9 --
10 -- Module PrelIO
11
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
15 -- module IO.
16
17 module PrelIO where
18
19 #include "HsStd.h"
20 #include "PrelHandle_hsc.h"
21 #include <string.h>
22
23 import PrelBase
24
25 import PrelPosix
26 import PrelMarshalAlloc
27 import PrelMarshalUtils
28 import PrelStorable
29 import PrelCError
30 import PrelCString
31 import PrelCTypes
32 import PrelCTypesISO
33
34 import PrelIOBase
35 import PrelHandle       -- much of the real stuff is in here
36
37 import PrelMaybe
38 import PrelReal
39 import PrelNum
40 import PrelRead
41 import PrelShow
42 import PrelMaybe        ( Maybe(..) )
43 import PrelPtr
44 import PrelList
45 import PrelException    ( ioError, catch, throw )
46 import PrelConc
47
48 -- -----------------------------------------------------------------------------
49 -- Standard IO
50
51 putChar         :: Char -> IO ()
52 putChar c       =  hPutChar stdout c
53
54 putStr          :: String -> IO ()
55 putStr s        =  hPutStr stdout s
56
57 putStrLn        :: String -> IO ()
58 putStrLn s      =  do putStr s
59                       putChar '\n'
60
61 print           :: Show a => a -> IO ()
62 print x         =  putStrLn (show x)
63
64 getChar         :: IO Char
65 getChar         =  hGetChar stdin
66
67 getLine         :: IO String
68 getLine         =  hGetLine stdin
69
70 getContents     :: IO String
71 getContents     =  hGetContents stdin
72
73 interact        ::  (String -> String) -> IO ()
74 interact f      =   do s <- getContents
75                        putStr (f s)
76
77 readFile        :: FilePath -> IO String
78 readFile name   =  openFile name ReadMode >>= hGetContents
79
80 writeFile       :: FilePath -> String -> IO ()
81 writeFile name str = do
82     hdl <- openFile name WriteMode
83     hPutStr hdl str
84     hClose hdl
85
86 appendFile      :: FilePath -> String -> IO ()
87 appendFile name str = do
88     hdl <- openFile name AppendMode
89     hPutStr hdl str
90     hClose hdl
91
92 readLn          :: Read a => IO a
93 readLn          =  do l <- getLine
94                       r <- readIO l
95                       return r
96
97   -- raises an exception instead of an error
98 readIO          :: Read a => String -> IO a
99 readIO s        =  case (do { (x,t) <- reads s ;
100                               ("","") <- lex t ;
101                               return x }) of
102 #ifndef NEW_READS_REP
103                         [x]    -> return x
104                         []     -> ioError (userError "Prelude.readIO: no parse")
105                         _      -> ioError (userError "Prelude.readIO: ambiguous parse")
106 #else
107                         Just x -> return x
108                         Nothing  -> ioError (userError "Prelude.readIO: no parse")
109 #endif
110
111 -- ---------------------------------------------------------------------------
112 -- Simple input operations
113
114 -- Computation "hReady hdl" indicates whether at least
115 -- one item is available for input from handle "hdl".
116
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.
121
122 hReady :: Handle -> IO Bool
123 hReady h = hWaitForInput h 0
124
125 hWaitForInput :: Handle -> Int -> IO Bool
126 hWaitForInput h msecs = do
127   wantReadableHandle "hReady" h $ \ handle_ -> do
128   let ref = haBuffer handle_
129   buf <- readIORef ref
130
131   if not (bufferEmpty buf)
132         then return True
133         else do
134
135   r <- throwErrnoIfMinus1Retry "hReady"
136           (inputReady (fromIntegral (haFD handle_)) (fromIntegral msecs))
137   return (r /= 0)
138
139 foreign import "inputReady" 
140   inputReady :: CInt -> CInt -> IO CInt
141
142 -- ---------------------------------------------------------------------------
143 -- hGetChar
144
145 -- hGetChar reads the next character from a handle,
146 -- blocking until a character is available.
147
148 hGetChar :: Handle -> IO Char
149 hGetChar handle =
150   wantReadableHandle "hGetChar" handle $ \handle_ -> do
151
152   let fd = haFD handle_
153       ref = haBuffer handle_
154
155   buf <- readIORef ref
156   if not (bufferEmpty buf)
157         then hGetcBuffered fd ref buf
158         else do
159
160   -- buffer is empty.
161   case haBufferMode handle_ of
162     LineBuffering    -> do
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
168     NoBuffering -> do
169         -- make use of the minimal buffer we already have
170         let raw = bufBuf buf
171         r <- throwErrnoIfMinus1RetryMayBlock "hGetChar"
172                 (read_off (fromIntegral fd) raw 0 1)
173                 (threadWaitRead fd)
174         if r == 0
175            then ioe_EOF
176            else do (c,_) <- readCharFromBuffer raw 0
177                    return c
178
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
184       return c
185
186 -- ---------------------------------------------------------------------------
187 -- hGetLine
188
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.
192
193 -- ToDo: the unbuffered case is wrong: it doesn't lock the handle for
194 -- the duration.
195 hGetLine :: Handle -> IO String
196 hGetLine h = do
197   m <- wantReadableHandle "hGetLine" h $ \ handle_ -> do
198         case haBufferMode handle_ of
199            NoBuffering      -> return Nothing
200            LineBuffering    -> do
201               l <- hGetLineBuffered handle_
202               return (Just l)
203            BlockBuffering _ -> do 
204               l <- hGetLineBuffered handle_
205               return (Just l)
206   case m of
207         Nothing -> hGetLineUnBuffered h
208         Just l  -> return l
209
210
211 hGetLineBuffered handle_ = do
212   let ref = haBuffer handle_
213   buf <- readIORef ref
214   hGetLineBufferedLoop handle_ ref buf []
215
216
217 hGetLineBufferedLoop handle_ ref 
218         buf@Buffer{ bufRPtr=r, bufWPtr=w, bufBuf=raw } xss =
219   let 
220         -- find the end-of-line character, if there is one
221         loop raw r
222            | r == w = return (False, w)
223            | otherwise =  do
224                 (c,r') <- readCharFromBuffer raw r
225                 if c == '\n' 
226                    then return (True, r) -- NB. not r': don't include the '\n'
227                    else loop raw r'
228   in do
229   (eol, off) <- loop raw r
230
231 #ifdef DEBUG_DUMP
232   puts ("hGetLineBufferedLoop: r=" ++ show r ++ ", w=" ++ show w ++ ", off=" ++ show off ++ "\n")
233 #endif
234
235   xs <- unpack raw r off
236   if eol
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)))
241         else do
242              maybe_buf <- maybeFillReadBuffer (haFD handle_) True 
243                                 buf{ bufWPtr=0, bufRPtr=0 }
244              case maybe_buf of
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
248                            if not (null str)
249                               then return str
250                               else ioe_EOF
251                 Just new_buf -> 
252                      hGetLineBufferedLoop handle_ ref new_buf (xs:xss)
253
254
255 maybeFillReadBuffer fd is_line buf
256   = catch 
257      (do buf <- fillReadBuffer fd is_line buf
258          return (Just buf)
259      )
260      (\e -> do if isEOFError e 
261                   then return Nothing 
262                   else throw e)
263
264
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
268    where
269     unpack acc i s
270      | i <## r  = (## s, acc ##)
271      | otherwise = 
272           case readCharArray## buf i s of
273             (## s, ch ##) -> unpack (C## ch : acc) (i -## 1##) s
274
275
276 hGetLineUnBuffered :: Handle -> IO String
277 hGetLineUnBuffered h = do
278   c <- hGetChar h
279   if c == '\n' then
280      return ""
281    else do
282     l <- getRest
283     return (c:l)
284  where
285   getRest = do
286     c <- 
287       catch 
288         (hGetChar h)
289         (\ err -> do
290           if isEOFError err then
291              return '\n'
292            else
293              ioError err)
294     if c == '\n' then
295        return ""
296      else do
297        s <- getRest
298        return (c:s)
299
300 -- -----------------------------------------------------------------------------
301 -- hGetContents
302
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.
306
307 -- hGetContents on a DuplexHandle only affects the read side: you can
308 -- carry on writing to it afterwards.
309
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 )
320
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.
324
325 lazyRead :: Handle -> IO String
326 lazyRead handle = 
327    unsafeInterleaveIO $
328         withHandle "lazyRead" handle $ \ handle_ -> do
329         case haType handle_ of
330           ClosedHandle     -> return (handle_, "")
331           SemiClosedHandle -> lazyRead' handle handle_
332           _ -> ioException 
333                   (IOError (Just handle) IllegalOperation "lazyRead"
334                         "illegal handle type" Nothing)
335
336 lazyRead' h handle_ = do
337   let ref = haBuffer handle_
338       fd  = haFD handle_
339
340   -- even a NoBuffering handle can have a char in the buffer... 
341   -- (see hLookAhead)
342   buf <- readIORef ref
343   if not (bufferEmpty buf)
344         then lazyReadHaveBuffer h handle_ fd ref buf
345         else do
346
347   case haBufferMode handle_ of
348      NoBuffering      -> do
349         -- make use of the minimal buffer we already have
350         let raw = bufBuf buf
351             fd  = haFD handle_
352         r <- throwErrnoIfMinus1RetryMayBlock "lazyRead"
353                 (read_off (fromIntegral fd) raw 0 1)
354                 (threadWaitRead fd)
355         if r == 0
356            then do handle_ <- hClose_help handle_ 
357                    return (handle_, "")
358            else do (c,_) <- readCharFromBuffer raw 0
359                    rest <- lazyRead h
360                    return (handle_, c : rest)
361
362      LineBuffering    -> lazyReadBuffered h handle_ fd ref buf
363      BlockBuffering _ -> lazyReadBuffered h handle_ fd ref buf
364
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
368    catch 
369         (do buf <- fillReadBuffer fd True{-is_line-} buf
370             lazyReadHaveBuffer h handle_ fd ref buf
371         )
372         -- all I/O errors are discarded.  Additionally, we close the handle.
373         (\e -> do handle_ <- hClose_help handle_
374                   return (handle_, "")
375         )
376
377 lazyReadHaveBuffer h handle_ fd ref buf = do
378    more <- lazyRead h
379    writeIORef ref buf{ bufRPtr=0, bufWPtr=0 }
380    s <- unpackAcc (bufBuf buf) (bufRPtr buf) (bufWPtr buf) more
381    return (handle_, s)
382
383
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
387    where
388     unpack acc i s
389      | i <## r  = (## s, acc ##)
390      | otherwise = 
391           case readCharArray## buf i s of
392             (## s, ch ##) -> unpack (C## ch : acc) (i -## 1##) s
393
394 -- ---------------------------------------------------------------------------
395 -- hPutChar
396
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'.
400
401 hPutChar :: Handle -> Char -> IO ()
402 hPutChar handle c = 
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
409         NoBuffering      ->
410                 withObject (castCharToCChar c) $ \buf ->
411                 throwErrnoIfMinus1RetryMayBlock_ "hPutChar"
412                    (c_write (fromIntegral fd) buf 1)
413                    (threadWaitWrite fd)
414
415
416 hPutcBuffered handle_ is_line c = do
417   let ref = haBuffer handle_
418   buf <- readIORef ref
419   let w = bufWPtr buf
420   w'  <- writeCharIntoBuffer (bufBuf buf) w c
421   let new_buf = buf{ bufWPtr = w' }
422   if bufferFull new_buf || is_line && c == '\n'
423      then do 
424         flushed_buf <- flushWriteBuffer (haFD handle_) new_buf
425         writeIORef ref flushed_buf
426      else do 
427         writeIORef ref new_buf
428
429
430 hPutChars :: Handle -> [Char] -> IO ()
431 hPutChars handle [] = return ()
432 hPutChars handle (c:cs) = hPutChar handle c >> hPutChars handle cs
433
434 -- ---------------------------------------------------------------------------
435 -- hPutStr
436
437 -- `hPutStr hdl s' writes the string `s' to the file or
438 -- hannel managed by `hdl', buffering the output if needs be.
439
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
443 -- case is
444 --
445 --              putStr (trace "hello" "world")
446 --
447 -- so the basic scheme is this:
448 --
449 --      * copy the string into a fresh buffer,
450 --      * "commit" the buffer to the handle.
451 --
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.
456
457 hPutStr :: Handle -> String -> IO ()
458 hPutStr handle str = do
459     buffer_mode <- wantWritableHandle "hPutStr" handle 
460                         (\ handle_ -> do getSpareBuffer handle_)
461     case buffer_mode of
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
468
469
470 getSpareBuffer :: Handle__ -> IO (BufferMode, Buffer)
471 getSpareBuffer Handle__{haBuffer=ref, 
472                         haBuffers=spare_ref,
473                         haBufferMode=mode}
474  = do
475    case mode of
476      NoBuffering -> return (mode, error "no buffer!")
477      _ -> do
478           bufs <- readIORef spare_ref
479           buf  <- readIORef ref
480           case bufs of
481             BufferListCons b rest -> do
482                 writeIORef spare_ref rest
483                 return ( mode, newEmptyBuffer b WriteBuffer (bufSize buf))
484             BufferListNil -> do
485                 new_buf <- allocateBuffer (bufSize buf) WriteBuffer
486                 return (mode, new_buf)
487
488
489 writeLines :: Handle -> Buffer -> String -> IO ()
490 writeLines hdl Buffer{ bufBuf=raw, bufSize=len } s =
491   let
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-}
499         return ()
500    shoveString n (c:cs) = do
501         n' <- writeCharIntoBuffer raw n c
502         shoveString n' cs
503   in
504   shoveString 0 s
505
506 writeBlocks :: Handle -> Buffer -> String -> IO ()
507 writeBlocks hdl Buffer{ bufBuf=raw, bufSize=len } s =
508   let
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-}
516         return ()
517    shoveString n (c:cs) = do
518         n' <- writeCharIntoBuffer raw n c
519         shoveString n' cs
520   in
521   shoveString 0 s
522
523 -- -----------------------------------------------------------------------------
524 -- commitBuffer handle buf sz count flush release
525 -- 
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).
528 -- 
529 -- Implementation:
530 -- 
531 --    for block/line buffering,
532 --       1. If there isn't room in the handle buffer, flush the handle
533 --          buffer.
534 -- 
535 --       2. If the handle buffer is empty,
536 --               if flush, 
537 --                   then write buf directly to the device.
538 --                   else swap the handle buffer with buf.
539 -- 
540 --       3. If the handle buffer is non-empty, copy buf into the
541 --          handle buffer.  Then, if flush != 0, flush
542 --          the buffer.
543
544 commitBuffer
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?
550         -> IO Buffer
551
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
555
556 #ifdef DEBUG_DUMP
557       puts ("commitBuffer: sz=" ++ show sz ++ ", count=" ++ show count
558             ++ ", flush=" ++ show flush ++ ", release=" ++ show release ++"\n")
559 #endif
560
561       old_buf@Buffer{ bufBuf=old_raw, bufRPtr=r, bufWPtr=w, bufSize=size }
562           <- readIORef ref
563
564       buf_ret <-
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.
573
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)
579
580                 -- else, we have to flush
581             else do flushed_buf <- flushWriteBuffer fd old_buf
582
583                     let this_buf = 
584                             Buffer{ bufBuf=raw, bufState=WriteBuffer, 
585                                     bufRPtr=0, bufWPtr=count, bufSize=sz }
586
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)
592                         then do 
593                           writeIORef ref this_buf
594                           return flushed_buf                         
595
596                         -- otherwise, we have to flush the new data too,
597                         -- and start with a fresh buffer
598                         else do 
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.
603                           if sz == size
604                              then return (newEmptyBuffer raw WriteBuffer sz)
605                              else allocateBuffer size WriteBuffer
606
607       -- release the buffer if necessary
608       if release && bufSize buf_ret == size
609          then do
610               spare_bufs <- readIORef spare_buf_ref
611               writeIORef spare_buf_ref 
612                 (BufferListCons (bufBuf buf_ret) spare_bufs)
613               return buf_ret
614          else
615               return buf_ret
616
617
618 foreign import "memcpy_wrap" unsafe 
619    memcpy_off :: RawBuffer -> Int -> RawBuffer -> CSize -> IO (Ptr ())
620 #def inline \
621 void *memcpy_wrap(char *dst, HsInt dst_off, const char *src, size_t sz) \
622 { return memcpy(dst+dst_off, src, sz); }
623
624 -- ---------------------------------------------------------------------------
625 -- hPutStrLn
626
627 -- Derived action `hPutStrLn hdl str' writes the string `str' to
628 -- the handle `hdl', adding a newline at the end.
629
630 hPutStrLn :: Handle -> String -> IO ()
631 hPutStrLn hndl str = do
632  hPutStr  hndl str
633  hPutChar hndl '\n'
634
635 -- ---------------------------------------------------------------------------
636 -- hPrint
637
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'.
640
641 hPrint :: Show a => Handle -> a -> IO ()
642 hPrint hdl = hPutStrLn hdl . show