[project @ 2001-12-03 20:59:08 by sof]
[ghc-hetmet.git] / ghc / lib / std / PrelIOBase.lhs
1 % ------------------------------------------------------------------------------
2 % $Id: PrelIOBase.lhs,v 1.45 2001/11/26 20:04:00 sof Exp $
3
4 % (c) The University of Glasgow, 1994-2001
5 %
6
7 % Definitions for the @IO@ monad and its friends.  Everything is exported
8 % concretely; the @IO@ module itself exports abstractly.
9
10 \begin{code}
11 {-# OPTIONS -fno-implicit-prelude #-}
12 module PrelIOBase where
13
14 import PrelST
15 import PrelArr
16 import PrelBase
17 import PrelNum  -- To get fromInteger etc, needed because of -fno-implicit-prelude
18 import PrelMaybe  ( Maybe(..) )
19 import PrelShow
20 import PrelList
21 import PrelRead
22 import PrelDynamic
23
24 -- ---------------------------------------------------------------------------
25 -- The IO Monad
26
27 {-
28 The IO Monad is just an instance of the ST monad, where the state is
29 the real world.  We use the exception mechanism (in PrelException) to
30 implement IO exceptions.
31
32 NOTE: The IO representation is deeply wired in to various parts of the
33 system.  The following list may or may not be exhaustive:
34
35 Compiler  - types of various primitives in PrimOp.lhs
36
37 RTS       - forceIO (StgMiscClosures.hc)
38           - catchzh_fast, (un)?blockAsyncExceptionszh_fast, raisezh_fast 
39             (Exceptions.hc)
40           - raiseAsync (Schedule.c)
41
42 Prelude   - PrelIOBase.lhs, and several other places including
43             PrelException.lhs.
44
45 Libraries - parts of hslibs/lang.
46
47 --SDM
48 -}
49
50 newtype IO a = IO (State# RealWorld -> (# State# RealWorld, a #))
51
52 unIO :: IO a -> (State# RealWorld -> (# State# RealWorld, a #))
53 unIO (IO a) = a
54
55 instance  Functor IO where
56    fmap f x = x >>= (return . f)
57
58 instance  Monad IO  where
59     {-# INLINE return #-}
60     {-# INLINE (>>)   #-}
61     {-# INLINE (>>=)  #-}
62     m >> k      =  m >>= \ _ -> k
63     return x    = returnIO x
64
65     m >>= k     = bindIO m k
66     fail s      = failIO s
67
68 failIO :: String -> IO a
69 failIO s = ioError (userError s)
70
71 liftIO :: IO a -> State# RealWorld -> STret RealWorld a
72 liftIO (IO m) = \s -> case m s of (# s', r #) -> STret s' r
73
74 bindIO :: IO a -> (a -> IO b) -> IO b
75 bindIO (IO m) k = IO ( \ s ->
76   case m s of 
77     (# new_s, a #) -> unIO (k a) new_s
78   )
79
80 returnIO :: a -> IO a
81 returnIO x = IO (\ s -> (# s, x #))
82
83 -- ---------------------------------------------------------------------------
84 -- Coercions between IO and ST
85
86 --stToIO        :: (forall s. ST s a) -> IO a
87 stToIO        :: ST RealWorld a -> IO a
88 stToIO (ST m) = IO m
89
90 ioToST        :: IO a -> ST RealWorld a
91 ioToST (IO m) = (ST m)
92
93 -- ---------------------------------------------------------------------------
94 -- Unsafe IO operations
95
96 {-# NOINLINE unsafePerformIO #-}
97 unsafePerformIO :: IO a -> a
98 unsafePerformIO (IO m) = case m realWorld# of (# _, r #)   -> r
99
100 {-# NOINLINE unsafeInterleaveIO #-}
101 unsafeInterleaveIO :: IO a -> IO a
102 unsafeInterleaveIO (IO m)
103   = IO ( \ s -> let
104                    r = case m s of (# _, res #) -> res
105                 in
106                 (# s, r #))
107
108 -- ---------------------------------------------------------------------------
109 -- Handle type
110
111 data MVar a = MVar (MVar# RealWorld a)
112
113 -- pull in Eq (Mvar a) too, to avoid PrelConc being an orphan-instance module
114 instance Eq (MVar a) where
115         (MVar mvar1#) == (MVar mvar2#) = sameMVar# mvar1# mvar2#
116
117 --  A Handle is represented by (a reference to) a record 
118 --  containing the state of the I/O port/device. We record
119 --  the following pieces of info:
120
121 --    * type (read,write,closed etc.)
122 --    * the underlying file descriptor
123 --    * buffering mode 
124 --    * buffer, and spare buffers
125 --    * user-friendly name (usually the
126 --      FilePath used when IO.openFile was called)
127
128 -- Note: when a Handle is garbage collected, we want to flush its buffer
129 -- and close the OS file handle, so as to free up a (precious) resource.
130
131 data Handle 
132   = FileHandle                          -- A normal handle to a file
133         !(MVar Handle__)
134
135   | DuplexHandle                        -- A handle to a read/write stream
136         !(MVar Handle__)                -- The read side
137         !(MVar Handle__)                -- The write side
138
139 -- NOTES:
140 --    * A 'FileHandle' is seekable.  A 'DuplexHandle' may or may not be
141 --      seekable.
142
143 instance Eq Handle where
144  (FileHandle h1)     == (FileHandle h2)     = h1 == h2
145  (DuplexHandle h1 _) == (DuplexHandle h2 _) = h1 == h2
146  _ == _ = False 
147
148 type FD = Int -- XXX ToDo: should be CInt
149
150 data Handle__
151   = Handle__ {
152       haFD          :: !FD,                  -- file descriptor
153       haType        :: HandleType,           -- type (read/write/append etc.)
154       haIsBin       :: Bool,                 -- binary mode?
155       haIsStream    :: Bool,                 -- is this a stream handle?
156       haBufferMode  :: BufferMode,           -- buffer contains read/write data?
157       haFilePath    :: FilePath,             -- file name, possibly
158       haBuffer      :: !(IORef Buffer),      -- the current buffer
159       haBuffers     :: !(IORef BufferList),  -- spare buffers
160       haOtherSide   :: Maybe (MVar Handle__) -- ptr to the write side of a 
161                                              -- duplex handle.
162     }
163
164 -- ---------------------------------------------------------------------------
165 -- Buffers
166
167 -- The buffer is represented by a mutable variable containing a
168 -- record, where the record contains the raw buffer and the start/end
169 -- points of the filled portion.  We use a mutable variable so that
170 -- the common operation of writing (or reading) some data from (to)
171 -- the buffer doesn't need to modify, and hence copy, the handle
172 -- itself, it just updates the buffer.  
173
174 -- There will be some allocation involved in a simple hPutChar in
175 -- order to create the new Buffer structure (below), but this is
176 -- relatively small, and this only has to be done once per write
177 -- operation.
178
179 -- The buffer contains its size - we could also get the size by
180 -- calling sizeOfMutableByteArray# on the raw buffer, but that tends
181 -- to be rounded up to the nearest Word.
182
183 type RawBuffer = MutableByteArray# RealWorld
184
185 -- INVARIANTS on a Buffer:
186 --
187 --   * A handle *always* has a buffer, even if it is only 1 character long
188 --     (an unbuffered handle needs a 1 character buffer in order to support
189 --      hLookAhead and hIsEOF).
190 --   * r <= w
191 --   * if r == w, then r == 0 && w == 0
192 --   * if state == WriteBuffer, then r == 0
193 --   * a write buffer is never full.  If an operation
194 --     fills up the buffer, it will always flush it before 
195 --     returning.
196 --   * a read buffer may be full as a result of hLookAhead.  In normal
197 --     operation, a read buffer always has at least one character of space.
198
199 data Buffer 
200   = Buffer {
201         bufBuf   :: RawBuffer,
202         bufRPtr  :: !Int,
203         bufWPtr  :: !Int,
204         bufSize  :: !Int,
205         bufState :: BufferState
206   }
207
208 data BufferState = ReadBuffer | WriteBuffer deriving (Eq)
209
210 -- we keep a few spare buffers around in a handle to avoid allocating
211 -- a new one for each hPutStr.  These buffers are *guaranteed* to be the
212 -- same size as the main buffer.
213 data BufferList 
214   = BufferListNil 
215   | BufferListCons RawBuffer BufferList
216
217
218 bufferIsWritable :: Buffer -> Bool
219 bufferIsWritable Buffer{ bufState=WriteBuffer } = True
220 bufferIsWritable _other = False
221
222 bufferEmpty :: Buffer -> Bool
223 bufferEmpty Buffer{ bufRPtr=r, bufWPtr=w } = r == w
224
225 -- only makes sense for a write buffer
226 bufferFull :: Buffer -> Bool
227 bufferFull b@Buffer{ bufWPtr=w } = w >= bufSize b
228
229 --  Internally, we classify handles as being one
230 --  of the following:
231
232 data HandleType
233  = ClosedHandle
234  | SemiClosedHandle
235  | ReadHandle
236  | WriteHandle
237  | AppendHandle
238  | ReadWriteHandle
239
240 isReadableHandleType ReadHandle         = True
241 isReadableHandleType ReadWriteHandle    = True
242 isReadableHandleType _                  = False
243
244 isWritableHandleType AppendHandle    = True
245 isWritableHandleType WriteHandle     = True
246 isWritableHandleType ReadWriteHandle = True
247 isWritableHandleType _               = False
248
249 -- File names are specified using @FilePath@, a OS-dependent
250 -- string that (hopefully, I guess) maps to an accessible file/object.
251
252 type FilePath = String
253
254 -- ---------------------------------------------------------------------------
255 -- Buffering modes
256
257 -- Three kinds of buffering are supported: line-buffering, 
258 -- block-buffering or no-buffering.  These modes have the following
259 -- effects. For output, items are written out from the internal
260 -- buffer according to the buffer mode:
261 --
262 -- * line-buffering  the entire output buffer is written
263 --   out whenever a newline is output, the output buffer overflows, 
264 --   a flush is issued, or the handle is closed.
265 --
266 -- * block-buffering the entire output buffer is written out whenever 
267 --   it overflows, a flush is issued, or the handle
268 --   is closed.
269 --
270 -- * no-buffering output is written immediately, and never stored
271 --   in the output buffer.
272 --
273 -- The output buffer is emptied as soon as it has been written out.
274
275 -- Similarly, input occurs according to the buffer mode for handle {\em hdl}.
276
277 -- * line-buffering when the input buffer for the handle is not empty,
278 --   the next item is obtained from the buffer;
279 --   otherwise, when the input buffer is empty,
280 --   characters up to and including the next newline
281 --   character are read into the buffer.  No characters
282 --   are available until the newline character is
283 --   available.
284 --
285 -- * block-buffering when the input buffer for the handle becomes empty,
286 --   the next block of data is read into this buffer.
287 --
288 -- * no-buffering the next input item is read and returned.
289
290 -- For most implementations, physical files will normally be block-buffered 
291 -- and terminals will normally be line-buffered. (the IO interface provides
292 -- operations for changing the default buffering of a handle tho.)
293
294 data BufferMode  
295  = NoBuffering | LineBuffering | BlockBuffering (Maybe Int)
296    deriving (Eq, Ord, Read, Show)
297
298 -- ---------------------------------------------------------------------------
299 -- IORefs
300
301 newtype IORef a = IORef (STRef RealWorld a) deriving Eq
302
303 newIORef    :: a -> IO (IORef a)
304 newIORef v = stToIO (newSTRef v) >>= \ var -> return (IORef var)
305
306 readIORef   :: IORef a -> IO a
307 readIORef  (IORef var) = stToIO (readSTRef var)
308
309 writeIORef  :: IORef a -> a -> IO ()
310 writeIORef (IORef var) v = stToIO (writeSTRef var v)
311
312 modifyIORef :: IORef a -> (a -> a) -> IO ()
313 modifyIORef ref f = readIORef ref >>= \x -> writeIORef ref (f x)
314
315 -- deprecated, use modifyIORef
316 updateIORef :: IORef a -> (a -> a) -> IO ()
317 updateIORef = modifyIORef
318
319 -- ---------------------------------------------------------------------------
320 -- Show instance for Handles
321
322 -- handle types are 'show'n when printing error msgs, so
323 -- we provide a more user-friendly Show instance for it
324 -- than the derived one.
325
326 instance Show HandleType where
327   showsPrec p t =
328     case t of
329       ClosedHandle      -> showString "closed"
330       SemiClosedHandle  -> showString "semi-closed"
331       ReadHandle        -> showString "readable"
332       WriteHandle       -> showString "writable"
333       AppendHandle      -> showString "writable (append)"
334       ReadWriteHandle   -> showString "read-writable"
335
336 instance Show Handle where 
337   showsPrec p (FileHandle   h)   = showHandle p h False
338   showsPrec p (DuplexHandle _ h) = showHandle p h True
339    
340 showHandle p h duplex =
341     let
342      -- (Big) SIGH: unfolded defn of takeMVar to avoid
343      -- an (oh-so) unfortunate module loop with PrelConc.
344      hdl_ = unsafePerformIO (IO $ \ s# ->
345              case h                 of { MVar h# ->
346              case takeMVar# h# s#   of { (# s2# , r #) -> 
347              case putMVar# h# r s2# of { s3# ->
348              (# s3#, r #) }}})
349
350      showType | duplex = showString "duplex (read-write)"
351               | otherwise = showsPrec p (haType hdl_)
352     in
353     showChar '{' . 
354     showHdl (haType hdl_) 
355             (showString "loc=" . showString (haFilePath hdl_) . showChar ',' .
356              showString "type=" . showType . showChar ',' .
357              showString "binary=" . showsPrec p (haIsBin hdl_) . showChar ',' .
358              showString "buffering=" . showBufMode (unsafePerformIO (readIORef (haBuffer hdl_))) (haBufferMode hdl_) . showString "}" )
359    where
360
361     showHdl :: HandleType -> ShowS -> ShowS
362     showHdl ht cont = 
363        case ht of
364         ClosedHandle  -> showsPrec p ht . showString "}"
365         _ -> cont
366        
367     showBufMode :: Buffer -> BufferMode -> ShowS
368     showBufMode buf bmo =
369       case bmo of
370         NoBuffering   -> showString "none"
371         LineBuffering -> showString "line"
372         BlockBuffering (Just n) -> showString "block " . showParen True (showsPrec p n)
373         BlockBuffering Nothing  -> showString "block " . showParen True (showsPrec p def)
374       where
375        def :: Int 
376        def = bufSize buf
377
378 -- ------------------------------------------------------------------------
379 -- Exception datatype and operations
380
381 data Exception
382   = IOException         IOException     -- IO exceptions
383   | ArithException      ArithException  -- Arithmetic exceptions
384   | ArrayException      ArrayException  -- Array-related exceptions
385   | ErrorCall           String          -- Calls to 'error'
386   | ExitException       ExitCode        -- Call to System.exitWith
387   | NoMethodError       String          -- A non-existent method was invoked
388   | PatternMatchFail    String          -- A pattern match / guard failure
389   | RecSelError         String          -- Selecting a non-existent field
390   | RecConError         String          -- Field missing in record construction
391   | RecUpdError         String          -- Record doesn't contain updated field
392   | AssertionFailed     String          -- Assertions
393   | DynException        Dynamic         -- Dynamic exceptions
394   | AsyncException      AsyncException  -- Externally generated errors
395   | BlockedOnDeadMVar                   -- Blocking on a dead MVar
396   | NonTermination
397   | UserError           String
398
399 data ArithException
400   = Overflow
401   | Underflow
402   | LossOfPrecision
403   | DivideByZero
404   | Denormal
405   deriving (Eq, Ord)
406
407 data AsyncException
408   = StackOverflow
409   | HeapOverflow
410   | ThreadKilled
411   deriving (Eq, Ord)
412
413 data ArrayException
414   = IndexOutOfBounds    String          -- out-of-range array access
415   | UndefinedElement    String          -- evaluating an undefined element
416   deriving (Eq, Ord)
417
418 stackOverflow, heapOverflow :: Exception -- for the RTS
419 stackOverflow = AsyncException StackOverflow
420 heapOverflow  = AsyncException HeapOverflow
421
422 instance Show ArithException where
423   showsPrec _ Overflow        = showString "arithmetic overflow"
424   showsPrec _ Underflow       = showString "arithmetic underflow"
425   showsPrec _ LossOfPrecision = showString "loss of precision"
426   showsPrec _ DivideByZero    = showString "divide by zero"
427   showsPrec _ Denormal        = showString "denormal"
428
429 instance Show AsyncException where
430   showsPrec _ StackOverflow   = showString "stack overflow"
431   showsPrec _ HeapOverflow    = showString "heap overflow"
432   showsPrec _ ThreadKilled    = showString "thread killed"
433
434 instance Show ArrayException where
435   showsPrec _ (IndexOutOfBounds s)
436         = showString "array index out of range"
437         . (if not (null s) then showString ": " . showString s
438                            else id)
439   showsPrec _ (UndefinedElement s)
440         = showString "undefined array element"
441         . (if not (null s) then showString ": " . showString s
442                            else id)
443
444 instance Show Exception where
445   showsPrec _ (IOException err)          = shows err
446   showsPrec _ (ArithException err)       = shows err
447   showsPrec _ (ArrayException err)       = shows err
448   showsPrec _ (ErrorCall err)            = showString err
449   showsPrec _ (ExitException err)        = showString "exit: " . shows err
450   showsPrec _ (NoMethodError err)        = showString err
451   showsPrec _ (PatternMatchFail err)     = showString err
452   showsPrec _ (RecSelError err)          = showString err
453   showsPrec _ (RecConError err)          = showString err
454   showsPrec _ (RecUpdError err)          = showString err
455   showsPrec _ (AssertionFailed err)      = showString err
456   showsPrec _ (DynException _err)        = showString "unknown exception"
457   showsPrec _ (AsyncException e)         = shows e
458   showsPrec _ (BlockedOnDeadMVar)        = showString "thread blocked indefinitely"
459   showsPrec _ (NonTermination)           = showString "<<loop>>"
460   showsPrec _ (UserError err)            = showString err
461
462 -- -----------------------------------------------------------------------------
463 -- The ExitCode type
464
465 -- The `ExitCode' type defines the exit codes that a program
466 -- can return.  `ExitSuccess' indicates successful termination;
467 -- and `ExitFailure code' indicates program failure
468 -- with value `code'.  The exact interpretation of `code'
469 -- is operating-system dependent.  In particular, some values of 
470 -- `code' may be prohibited (e.g. 0 on a POSIX-compliant system).
471
472 -- We need it here because it is used in ExitException in the
473 -- Exception datatype (above).
474
475 data ExitCode = ExitSuccess | ExitFailure Int 
476                 deriving (Eq, Ord, Read, Show)
477
478 -- --------------------------------------------------------------------------
479 -- Primitive throw
480
481 throw :: Exception -> a
482 throw exception = raise# exception
483
484 ioError         :: Exception -> IO a 
485 ioError err     =  IO $ \s -> throw err s
486
487 ioException     :: IOException -> IO a
488 ioException err =  IO $ \s -> throw (IOException err) s
489
490 -- ---------------------------------------------------------------------------
491 -- IOError type
492
493 -- A value @IOError@ encode errors occurred in the @IO@ monad.
494 -- An @IOError@ records a more specific error type, a descriptive
495 -- string and maybe the handle that was used when the error was
496 -- flagged.
497
498 type IOError = Exception
499
500 data IOException
501  = IOError
502      (Maybe Handle)   -- the handle used by the action flagging the
503                       --   the error.
504      IOErrorType      -- what it was.
505      String           -- location.
506      String           -- error type specific information.
507      (Maybe FilePath) -- filename the error is related to.
508
509 instance Eq IOException where
510   (IOError h1 e1 loc1 str1 fn1) == (IOError h2 e2 loc2 str2 fn2) = 
511     e1==e2 && str1==str2 && h1==h2 && loc1==loc2 && fn1==fn2
512
513 data IOErrorType
514   = AlreadyExists        | HardwareFault
515   | IllegalOperation     | InappropriateType
516   | Interrupted          | InvalidArgument
517   | NoSuchThing          | OtherError
518   | PermissionDenied     | ProtocolError
519   | ResourceBusy         | ResourceExhausted
520   | ResourceVanished     | SystemError
521   | TimeExpired          | UnsatisfiedConstraints
522   | UnsupportedOperation
523   | EOF
524   | DynIOError Dynamic -- cheap&cheerful extensible IO error type.
525
526 instance Eq IOErrorType where
527    x == y = 
528      case x of
529        DynIOError{} -> False -- from a strictness POV, compatible with a derived Eq inst?
530        _ -> getTag# x ==# getTag# y
531
532 instance Show IOErrorType where
533   showsPrec _ e =
534     showString $
535     case e of
536       AlreadyExists     -> "already exists"
537       HardwareFault     -> "hardware fault"
538       IllegalOperation  -> "illegal operation"
539       InappropriateType -> "inappropriate type"
540       Interrupted       -> "interrupted"
541       InvalidArgument   -> "invalid argument"
542       NoSuchThing       -> "does not exist"
543       OtherError        -> "failed"
544       PermissionDenied  -> "permission denied"
545       ProtocolError     -> "protocol error"
546       ResourceBusy      -> "resource busy"
547       ResourceExhausted -> "resource exhausted"
548       ResourceVanished  -> "resource vanished"
549       SystemError       -> "system error"
550       TimeExpired       -> "timeout"
551       UnsatisfiedConstraints -> "unsatisified constraints" -- ultra-precise!
552       UnsupportedOperation -> "unsupported operation"
553       EOF               -> "end of file"
554       DynIOError{}      -> "unknown IO error"
555
556 userError       :: String  -> IOError
557 userError str   =  UserError str
558
559 -- ---------------------------------------------------------------------------
560 -- Predicates on IOError
561
562 isAlreadyExistsError :: IOError -> Bool
563 isAlreadyExistsError (IOException (IOError _ AlreadyExists _ _ _)) = True
564 isAlreadyExistsError _                                             = False
565
566 isAlreadyInUseError :: IOError -> Bool
567 isAlreadyInUseError (IOException (IOError _ ResourceBusy _ _ _)) = True
568 isAlreadyInUseError _                                            = False
569
570 isFullError :: IOError -> Bool
571 isFullError (IOException (IOError _ ResourceExhausted _ _ _)) = True
572 isFullError _                                                 = False
573
574 isEOFError :: IOError -> Bool
575 isEOFError (IOException (IOError _ EOF _ _ _)) = True
576 isEOFError _                                   = False
577
578 isIllegalOperation :: IOError -> Bool
579 isIllegalOperation (IOException (IOError _ IllegalOperation _ _ _)) = True
580 isIllegalOperation _                                                = False
581
582 isPermissionError :: IOError -> Bool
583 isPermissionError (IOException (IOError _ PermissionDenied _ _ _)) = True
584 isPermissionError _                                                = False
585
586 isDoesNotExistError :: IOError -> Bool
587 isDoesNotExistError (IOException (IOError _ NoSuchThing _ _ _)) = True
588 isDoesNotExistError _                                           = False
589
590 isUserError :: IOError -> Bool
591 isUserError (UserError _) = True
592 isUserError _             = False
593
594 -- ---------------------------------------------------------------------------
595 -- Showing IOErrors
596
597 instance Show IOException where
598     showsPrec p (IOError hdl iot loc s fn) =
599       showsPrec p iot .
600       (case loc of
601          "" -> id
602          _  -> showString "\nAction: " . showString loc) .
603       (case hdl of
604         Nothing -> id
605         Just h  -> showString "\nHandle: " . showsPrec p h) .
606       (case s of
607          "" -> id
608          _  -> showString "\nReason: " . showString s) .
609       (case fn of
610          Nothing -> id
611          Just name -> showString "\nFile: " . showString name)
612 \end{code}