[project @ 2001-08-04 06:10:04 by ken]
[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.8 2001/08/04 06:10:04 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
22 import PrelBase
23
24 import PrelPosix
25 import PrelMarshalAlloc
26 import PrelMarshalUtils
27 import PrelStorable
28 import PrelCError
29 import PrelCString
30 import PrelCTypes
31 import PrelCTypesISO
32
33 import PrelIOBase
34 import PrelHandle       -- much of the real stuff is in here
35
36 import PrelMaybe
37 import PrelReal
38 import PrelNum
39 import PrelRead
40 import PrelShow
41 import PrelMaybe        ( Maybe(..) )
42 import PrelPtr
43 import PrelList
44 import PrelException    ( ioError, catch, throw )
45 import PrelConc
46
47 -- -----------------------------------------------------------------------------
48 -- Standard IO
49
50 putChar         :: Char -> IO ()
51 putChar c       =  hPutChar stdout c
52
53 putStr          :: String -> IO ()
54 putStr s        =  hPutStr stdout s
55
56 putStrLn        :: String -> IO ()
57 putStrLn s      =  do putStr s
58                       putChar '\n'
59
60 print           :: Show a => a -> IO ()
61 print x         =  putStrLn (show x)
62
63 getChar         :: IO Char
64 getChar         =  hGetChar stdin
65
66 getLine         :: IO String
67 getLine         =  hGetLine stdin
68
69 getContents     :: IO String
70 getContents     =  hGetContents stdin
71
72 interact        ::  (String -> String) -> IO ()
73 interact f      =   do s <- getContents
74                        putStr (f s)
75
76 readFile        :: FilePath -> IO String
77 readFile name   =  openFile name ReadMode >>= hGetContents
78
79 writeFile       :: FilePath -> String -> IO ()
80 writeFile name str = do
81     hdl <- openFile name WriteMode
82     hPutStr hdl str
83     hClose hdl
84
85 appendFile      :: FilePath -> String -> IO ()
86 appendFile name str = do
87     hdl <- openFile name AppendMode
88     hPutStr hdl str
89     hClose hdl
90
91 readLn          :: Read a => IO a
92 readLn          =  do l <- getLine
93                       r <- readIO l
94                       return r
95
96   -- raises an exception instead of an error
97 readIO          :: Read a => String -> IO a
98 readIO s        =  case (do { (x,t) <- reads s ;
99                               ("","") <- lex t ;
100                               return x }) of
101 #ifndef NEW_READS_REP
102                         [x]    -> return x
103                         []     -> ioError (userError "Prelude.readIO: no parse")
104                         _      -> ioError (userError "Prelude.readIO: ambiguous parse")
105 #else
106                         Just x -> return x
107                         Nothing  -> ioError (userError "Prelude.readIO: no parse")
108 #endif
109
110 -- ---------------------------------------------------------------------------
111 -- Simple input operations
112
113 -- Computation "hReady hdl" indicates whether at least
114 -- one item is available for input from handle "hdl".
115
116 -- If hWaitForInput finds anything in the Handle's buffer, it
117 -- immediately returns.  If not, it tries to read from the underlying
118 -- OS handle. Notice that for buffered Handles connected to terminals
119 -- this means waiting until a complete line is available.
120
121 hReady :: Handle -> IO Bool
122 hReady h = hWaitForInput h 0
123
124 hWaitForInput :: Handle -> Int -> IO Bool
125 hWaitForInput h msecs = do
126   wantReadableHandle "hReady" h $ \ handle_ -> do
127   let ref = haBuffer handle_
128   buf <- readIORef ref
129
130   if not (bufferEmpty buf)
131         then return True
132         else do
133
134   r <- throwErrnoIfMinus1Retry "hReady"
135           (inputReady (fromIntegral (haFD handle_)) (fromIntegral msecs))
136   return (r /= 0)
137
138 foreign import "inputReady" 
139   inputReady :: CInt -> CInt -> IO CInt
140
141 -- ---------------------------------------------------------------------------
142 -- hGetChar
143
144 -- hGetChar reads the next character from a handle,
145 -- blocking until a character is available.
146
147 hGetChar :: Handle -> IO Char
148 hGetChar handle =
149   wantReadableHandle "hGetChar" handle $ \handle_ -> do
150
151   let fd = haFD handle_
152       ref = haBuffer handle_
153
154   buf <- readIORef ref
155   if not (bufferEmpty buf)
156         then hGetcBuffered fd ref buf
157         else do
158
159   -- buffer is empty.
160   case haBufferMode handle_ of
161     LineBuffering    -> do
162         new_buf <- fillReadBuffer fd True buf
163         hGetcBuffered fd ref new_buf
164     BlockBuffering _ -> do
165         new_buf <- fillReadBuffer fd False buf
166         hGetcBuffered fd ref new_buf
167     NoBuffering -> do
168         -- make use of the minimal buffer we already have
169         let raw = bufBuf buf
170         r <- throwErrnoIfMinus1RetryMayBlock "hGetChar"
171                 (read_off (fromIntegral fd) raw 0 1)
172                 (threadWaitRead fd)
173         if r == 0
174            then ioe_EOF
175            else do (c,_) <- readCharFromBuffer raw 0
176                    return c
177
178 hGetcBuffered fd ref buf@Buffer{ bufBuf=b, bufRPtr=r, bufWPtr=w }
179  = do (c,r) <- readCharFromBuffer b r
180       let new_buf | r == w    = buf{ bufRPtr=0, bufWPtr=0 }
181                   | otherwise = buf{ bufRPtr=r }
182       writeIORef ref new_buf
183       return c
184
185 -- ---------------------------------------------------------------------------
186 -- hGetLine
187
188 -- If EOF is reached before EOL is encountered, ignore the EOF and
189 -- return the partial line. Next attempt at calling hGetLine on the
190 -- handle will yield an EOF IO exception though.
191
192 -- ToDo: the unbuffered case is wrong: it doesn't lock the handle for
193 -- the duration.
194 hGetLine :: Handle -> IO String
195 hGetLine h = do
196   m <- wantReadableHandle "hGetLine" h $ \ handle_ -> do
197         case haBufferMode handle_ of
198            NoBuffering      -> return Nothing
199            LineBuffering    -> do
200               l <- hGetLineBuffered handle_
201               return (Just l)
202            BlockBuffering _ -> do 
203               l <- hGetLineBuffered handle_
204               return (Just l)
205   case m of
206         Nothing -> hGetLineUnBuffered h
207         Just l  -> return l
208
209
210 hGetLineBuffered handle_ = do
211   let ref = haBuffer handle_
212   buf <- readIORef ref
213   hGetLineBufferedLoop handle_ ref buf []
214
215
216 hGetLineBufferedLoop handle_ ref 
217         buf@Buffer{ bufRPtr=r, bufWPtr=w, bufBuf=raw } xss =
218   let 
219         -- find the end-of-line character, if there is one
220         loop raw r
221            | r == w = return (False, w)
222            | otherwise =  do
223                 (c,r') <- readCharFromBuffer raw r
224                 if c == '\n' 
225                    then return (True, r) -- NB. not r': don't include the '\n'
226                    else loop raw r'
227   in do
228   (eol, off) <- loop raw r
229
230 #ifdef DEBUG_DUMP
231   puts ("hGetLineBufferedLoop: r=" ++ show r ++ ", w=" ++ show w ++ ", off=" ++ show off ++ "\n")
232 #endif
233
234   xs <- unpack raw r off
235   if eol
236         then do if w == off + 1
237                    then writeIORef ref buf{ bufRPtr=0, bufWPtr=0 }
238                    else writeIORef ref buf{ bufRPtr = off + 1 }
239                 return (concat (reverse (xs:xss)))
240         else do
241              maybe_buf <- maybeFillReadBuffer (haFD handle_) True 
242                                 buf{ bufWPtr=0, bufRPtr=0 }
243              case maybe_buf of
244                 -- Nothing indicates we caught an EOF, and we may have a
245                 -- partial line to return.
246                 Nothing -> let str = concat (reverse (xs:xss)) in
247                            if not (null str)
248                               then return str
249                               else ioe_EOF
250                 Just new_buf -> 
251                      hGetLineBufferedLoop handle_ ref new_buf (xs:xss)
252
253
254 maybeFillReadBuffer fd is_line buf
255   = catch 
256      (do buf <- fillReadBuffer fd is_line buf
257          return (Just buf)
258      )
259      (\e -> do if isEOFError e 
260                   then return Nothing 
261                   else throw e)
262
263
264 unpack :: RawBuffer -> Int -> Int -> IO [Char]
265 unpack buf r 0   = return ""
266 unpack buf (I## r) (I## len) = IO $ \s -> unpack [] (len -## 1##) s
267    where
268     unpack acc i s
269      | i <## r  = (## s, acc ##)
270      | otherwise = 
271           case readCharArray## buf i s of
272             (## s, ch ##) -> unpack (C## ch : acc) (i -## 1##) s
273
274
275 hGetLineUnBuffered :: Handle -> IO String
276 hGetLineUnBuffered h = do
277   c <- hGetChar h
278   if c == '\n' then
279      return ""
280    else do
281     l <- getRest
282     return (c:l)
283  where
284   getRest = do
285     c <- 
286       catch 
287         (hGetChar h)
288         (\ err -> do
289           if isEOFError err then
290              return '\n'
291            else
292              ioError err)
293     if c == '\n' then
294        return ""
295      else do
296        s <- getRest
297        return (c:s)
298
299 -- -----------------------------------------------------------------------------
300 -- hGetContents
301
302 -- hGetContents returns the list of characters corresponding to the
303 -- unread portion of the channel or file managed by the handle, which
304 -- is made semi-closed.
305
306 -- hGetContents on a DuplexHandle only affects the read side: you can
307 -- carry on writing to it afterwards.
308
309 hGetContents :: Handle -> IO String
310 hGetContents handle = 
311     withHandle "hGetContents" handle $ \handle_ ->
312     case haType handle_ of 
313       ClosedHandle         -> ioe_closedHandle
314       SemiClosedHandle     -> ioe_closedHandle
315       AppendHandle         -> ioe_notReadable
316       WriteHandle          -> ioe_notReadable
317       _ -> do xs <- lazyRead handle
318               return (handle_{ haType=SemiClosedHandle}, xs )
319
320 -- Note that someone may close the semi-closed handle (or change its
321 -- buffering), so each time these lazy read functions are pulled on,
322 -- they have to check whether the handle has indeed been closed.
323
324 lazyRead :: Handle -> IO String
325 lazyRead handle = 
326    unsafeInterleaveIO $
327         withHandle "lazyRead" handle $ \ handle_ -> do
328         case haType handle_ of
329           ClosedHandle     -> return (handle_, "")
330           SemiClosedHandle -> lazyRead' handle handle_
331           _ -> ioException 
332                   (IOError (Just handle) IllegalOperation "lazyRead"
333                         "illegal handle type" Nothing)
334
335 lazyRead' h handle_ = do
336   let ref = haBuffer handle_
337       fd  = haFD handle_
338
339   -- even a NoBuffering handle can have a char in the buffer... 
340   -- (see hLookAhead)
341   buf <- readIORef ref
342   if not (bufferEmpty buf)
343         then lazyReadHaveBuffer h handle_ fd ref buf
344         else do
345
346   case haBufferMode handle_ of
347      NoBuffering      -> do
348         -- make use of the minimal buffer we already have
349         let raw = bufBuf buf
350             fd  = haFD handle_
351         r <- throwErrnoIfMinus1RetryMayBlock "lazyRead"
352                 (read_off (fromIntegral fd) raw 0 1)
353                 (threadWaitRead fd)
354         if r == 0
355            then do handle_ <- hClose_help handle_ 
356                    return (handle_, "")
357            else do (c,_) <- readCharFromBuffer raw 0
358                    rest <- lazyRead h
359                    return (handle_, c : rest)
360
361      LineBuffering    -> lazyReadBuffered h handle_ fd ref buf
362      BlockBuffering _ -> lazyReadBuffered h handle_ fd ref buf
363
364 -- we never want to block during the read, so we call fillReadBuffer with
365 -- is_line==True, which tells it to "just read what there is".
366 lazyReadBuffered h handle_ fd ref buf = do
367    catch 
368         (do buf <- fillReadBuffer fd True{-is_line-} buf
369             lazyReadHaveBuffer h handle_ fd ref buf
370         )
371         -- all I/O errors are discarded.  Additionally, we close the handle.
372         (\e -> do handle_ <- hClose_help handle_
373                   return (handle_, "")
374         )
375
376 lazyReadHaveBuffer h handle_ fd ref buf = do
377    more <- lazyRead h
378    writeIORef ref buf{ bufRPtr=0, bufWPtr=0 }
379    s <- unpackAcc (bufBuf buf) (bufRPtr buf) (bufWPtr buf) more
380    return (handle_, s)
381
382
383 unpackAcc :: RawBuffer -> Int -> Int -> [Char] -> IO [Char]
384 unpackAcc buf r 0 acc  = return ""
385 unpackAcc buf (I## r) (I## len) acc = IO $ \s -> unpack acc (len -## 1##) s
386    where
387     unpack acc i s
388      | i <## r  = (## s, acc ##)
389      | otherwise = 
390           case readCharArray## buf i s of
391             (## s, ch ##) -> unpack (C## ch : acc) (i -## 1##) s
392
393 -- ---------------------------------------------------------------------------
394 -- hPutChar
395
396 -- `hPutChar hdl ch' writes the character `ch' to the file or channel
397 -- managed by `hdl'.  Characters may be buffered if buffering is
398 -- enabled for `hdl'.
399
400 hPutChar :: Handle -> Char -> IO ()
401 hPutChar handle c = 
402     c `seq` do   -- must evaluate c before grabbing the handle lock
403     wantWritableHandle "hPutChar" handle $ \ handle_  -> do
404     let fd = haFD handle_
405     case haBufferMode handle_ of
406         LineBuffering    -> hPutcBuffered handle_ True  c
407         BlockBuffering _ -> hPutcBuffered handle_ False c
408         NoBuffering      ->
409                 withObject (castCharToCChar c) $ \buf ->
410                 throwErrnoIfMinus1RetryMayBlock_ "hPutChar"
411                    (c_write (fromIntegral fd) buf 1)
412                    (threadWaitWrite fd)
413
414
415 hPutcBuffered handle_ is_line c = do
416   let ref = haBuffer handle_
417   buf <- readIORef ref
418   let w = bufWPtr buf
419   w'  <- writeCharIntoBuffer (bufBuf buf) w c
420   let new_buf = buf{ bufWPtr = w' }
421   if bufferFull new_buf || is_line && c == '\n'
422      then do 
423         flushed_buf <- flushWriteBuffer (haFD handle_) new_buf
424         writeIORef ref flushed_buf
425      else do 
426         writeIORef ref new_buf
427
428
429 hPutChars :: Handle -> [Char] -> IO ()
430 hPutChars handle [] = return ()
431 hPutChars handle (c:cs) = hPutChar handle c >> hPutChars handle cs
432
433 -- ---------------------------------------------------------------------------
434 -- hPutStr
435
436 -- `hPutStr hdl s' writes the string `s' to the file or
437 -- hannel managed by `hdl', buffering the output if needs be.
438
439 -- We go to some trouble to avoid keeping the handle locked while we're
440 -- evaluating the string argument to hPutStr, in case doing so triggers another
441 -- I/O operation on the same handle which would lead to deadlock.  The classic
442 -- case is
443 --
444 --              putStr (trace "hello" "world")
445 --
446 -- so the basic scheme is this:
447 --
448 --      * copy the string into a fresh buffer,
449 --      * "commit" the buffer to the handle.
450 --
451 -- Committing may involve simply copying the contents of the new
452 -- buffer into the handle's buffer, flushing one or both buffers, or
453 -- maybe just swapping the buffers over (if the handle's buffer was
454 -- empty).  See commitBuffer below.
455
456 hPutStr :: Handle -> String -> IO ()
457 hPutStr handle str = do
458     buffer_mode <- wantWritableHandle "hPutStr" handle 
459                         (\ handle_ -> do getSpareBuffer handle_)
460     case buffer_mode of
461        (NoBuffering, _) -> do
462             hPutChars handle str        -- v. slow, but we don't care
463        (LineBuffering, buf) -> do
464             writeLines handle buf str
465        (BlockBuffering _, buf) -> do
466             writeBlocks handle buf str
467
468
469 getSpareBuffer :: Handle__ -> IO (BufferMode, Buffer)
470 getSpareBuffer Handle__{haBuffer=ref, 
471                         haBuffers=spare_ref,
472                         haBufferMode=mode}
473  = do
474    case mode of
475      NoBuffering -> return (mode, error "no buffer!")
476      _ -> do
477           bufs <- readIORef spare_ref
478           buf  <- readIORef ref
479           case bufs of
480             BufferListCons b rest -> do
481                 writeIORef spare_ref rest
482                 return ( mode, newEmptyBuffer b WriteBuffer (bufSize buf))
483             BufferListNil -> do
484                 new_buf <- allocateBuffer (bufSize buf) WriteBuffer
485                 return (mode, new_buf)
486
487
488 writeLines :: Handle -> Buffer -> String -> IO ()
489 writeLines hdl Buffer{ bufBuf=raw, bufSize=len } s =
490   let
491    shoveString :: Int -> [Char] -> IO ()
492         -- check n == len first, to ensure that shoveString is strict in n.
493    shoveString n cs | n == len = do
494         new_buf <- commitBuffer hdl raw len n True{-needs flush-} False
495         writeBlocks hdl new_buf cs
496    shoveString n [] = do
497         commitBuffer hdl raw len n False{-no flush-} True{-release-}
498         return ()
499    shoveString n (c:cs) = do
500         n' <- writeCharIntoBuffer raw n c
501         shoveString n' cs
502   in
503   shoveString 0 s
504
505 writeBlocks :: Handle -> Buffer -> String -> IO ()
506 writeBlocks hdl Buffer{ bufBuf=raw, bufSize=len } s =
507   let
508    shoveString :: Int -> [Char] -> IO ()
509         -- check n == len first, to ensure that shoveString is strict in n.
510    shoveString n cs | n == len = do
511         new_buf <- commitBuffer hdl raw len n True{-needs flush-} False
512         writeBlocks hdl new_buf cs
513    shoveString n [] = do
514         commitBuffer hdl raw len n False{-no flush-} True{-release-}
515         return ()
516    shoveString n (c:cs) = do
517         n' <- writeCharIntoBuffer raw n c
518         shoveString n' cs
519   in
520   shoveString 0 s
521
522 -- -----------------------------------------------------------------------------
523 -- commitBuffer handle buf sz count flush release
524 -- 
525 -- Write the contents of the buffer 'buf' ('sz' bytes long, containing
526 -- 'count' bytes of data) to handle (handle must be block or line buffered).
527 -- 
528 -- Implementation:
529 -- 
530 --    for block/line buffering,
531 --       1. If there isn't room in the handle buffer, flush the handle
532 --          buffer.
533 -- 
534 --       2. If the handle buffer is empty,
535 --               if flush, 
536 --                   then write buf directly to the device.
537 --                   else swap the handle buffer with buf.
538 -- 
539 --       3. If the handle buffer is non-empty, copy buf into the
540 --          handle buffer.  Then, if flush != 0, flush
541 --          the buffer.
542
543 commitBuffer
544         :: Handle                       -- handle to commit to
545         -> RawBuffer -> Int             -- address and size (in bytes) of buffer
546         -> Int                          -- number of bytes of data in buffer
547         -> Bool                         -- flush the handle afterward?
548         -> Bool                         -- release the buffer?
549         -> IO Buffer
550
551 commitBuffer hdl raw sz count flush release = do
552   wantWritableHandle "commitAndReleaseBuffer" hdl $ 
553     \ handle_@Handle__{ haFD=fd, haBuffer=ref, haBuffers=spare_buf_ref } -> do
554
555 #ifdef DEBUG_DUMP
556       puts ("commitBuffer: sz=" ++ show sz ++ ", count=" ++ show count
557             ++ ", flush=" ++ show flush ++ ", release=" ++ show release ++"\n")
558 #endif
559
560       old_buf@Buffer{ bufBuf=old_raw, bufRPtr=r, bufWPtr=w, bufSize=size }
561           <- readIORef ref
562
563       buf_ret <-
564         -- enough room in handle buffer?
565          if (not flush && (size - w > count))
566                 -- The > is to be sure that we never exactly fill
567                 -- up the buffer, which would require a flush.  So
568                 -- if copying the new data into the buffer would
569                 -- make the buffer full, we just flush the existing
570                 -- buffer and the new data immediately, rather than
571                 -- copying before flushing.
572
573                 -- not flushing, and there's enough room in the buffer:
574                 -- just copy the data in and update bufWPtr.
575             then do memcpy_off old_raw w raw (fromIntegral count)
576                     writeIORef ref old_buf{ bufWPtr = w + count }
577                     return (newEmptyBuffer raw WriteBuffer sz)
578
579                 -- else, we have to flush
580             else do flushed_buf <- flushWriteBuffer fd old_buf
581
582                     let this_buf = 
583                             Buffer{ bufBuf=raw, bufState=WriteBuffer, 
584                                     bufRPtr=0, bufWPtr=count, bufSize=sz }
585
586                         -- if:  (a) we don't have to flush, and
587                         --      (b) size(new buffer) == size(old buffer), and
588                         --      (c) new buffer is not full,
589                         -- we can just just swap them over...
590                     if (not flush && sz == size && count /= sz)
591                         then do 
592                           writeIORef ref this_buf
593                           return flushed_buf                         
594
595                         -- otherwise, we have to flush the new data too,
596                         -- and start with a fresh buffer
597                         else do 
598                           flushWriteBuffer fd this_buf
599                           writeIORef ref flushed_buf
600                             -- if the sizes were different, then allocate
601                             -- a new buffer of the correct size.
602                           if sz == size
603                              then return (newEmptyBuffer raw WriteBuffer sz)
604                              else allocateBuffer size WriteBuffer
605
606       -- release the buffer if necessary
607       if release && bufSize buf_ret == size
608          then do
609               spare_bufs <- readIORef spare_buf_ref
610               writeIORef spare_buf_ref 
611                 (BufferListCons (bufBuf buf_ret) spare_bufs)
612               return buf_ret
613          else
614               return buf_ret
615
616
617 foreign import "memcpy_wrap" unsafe 
618    memcpy_off :: RawBuffer -> Int -> RawBuffer -> CSize -> IO (Ptr ())
619 #def inline \
620 void *memcpy_wrap(char *dst, HsInt dst_off, const char *src, size_t sz) \
621 { return memcpy(dst+dst_off, src, sz); }
622
623 -- ---------------------------------------------------------------------------
624 -- hPutStrLn
625
626 -- Derived action `hPutStrLn hdl str' writes the string `str' to
627 -- the handle `hdl', adding a newline at the end.
628
629 hPutStrLn :: Handle -> String -> IO ()
630 hPutStrLn hndl str = do
631  hPutStr  hndl str
632  hPutChar hndl '\n'
633
634 -- ---------------------------------------------------------------------------
635 -- hPrint
636
637 -- Computation `hPrint hdl t' writes the string representation of `t'
638 -- given by the `shows' function to the file or channel managed by `hdl'.
639
640 hPrint :: Show a => Handle -> a -> IO ()
641 hPrint hdl = hPutStrLn hdl . show