1 % -----------------------------------------------------------------------------
2 % $Id: PrelIOBase.lhs,v 1.18 2000/03/14 01:52:25 sof Exp $
4 % (c) The AQUA Project, Glasgow University, 1994-1998
7 \section[PrelIOBase]{Module @PrelIOBase@}
9 Definitions for the @IO@ monad and its friends. Everything is exported
10 concretely; the @IO@ module itself exports abstractly.
13 {-# OPTIONS -fno-implicit-prelude -#include "cbits/stgio.h" #-}
14 #include "cbits/stgerror.h"
17 #ifndef __HUGS__ /* Hugs just includes this in PreludeBuiltin so no header needed */
18 module PrelIOBase where
20 import {-# SOURCE #-} PrelErr ( error )
24 import {-# SOURCE #-} PrelException ( ioError )
25 import PrelST ( ST(..), STret(..) )
26 import PrelMaybe ( Maybe(..) )
27 import PrelAddr ( Addr(..), nullAddr )
28 import PrelPack ( unpackCString )
31 #if !defined(__CONCURRENT_HASKELL__)
32 import PrelArr ( MutableVar, readVar )
37 #define __CONCURRENT_HASKELL__
39 #define unpackCString primUnpackString
42 #ifndef __PARALLEL_HASKELL__
43 #define FILE_OBJECT ForeignObj
45 #define FILE_OBJECT Addr
49 %*********************************************************
51 \subsection{The @IO@ monad}
53 %*********************************************************
55 The IO Monad is just an instance of the ST monad, where the state is
56 the real world. We use the exception mechanism (in PrelException) to
57 implement IO exceptions.
59 NOTE: The IO representation is deeply wired in to various parts of the
60 system. The following list may or may not be exhaustive:
62 Compiler - types of various primitives in PrimOp.lhs
64 RTS - forceIO (StgMiscClosures.hc)
65 - catchzh_fast, (un)?blockAsyncExceptionszh_fast, raisezh_fast
67 - raiseAsync (Schedule.c)
69 Prelude - PrelIOBase.lhs, and several other places including
72 Libraries - parts of hslibs/lang.
78 newtype IO a = IO (State# RealWorld -> (# State# RealWorld, a #))
80 unIO :: IO a -> (State# RealWorld -> (# State# RealWorld, a #))
83 instance Functor IO where
84 fmap f x = x >>= (return . f)
86 instance Monad IO where
90 m >> k = m >>= \ _ -> k
91 return x = IO $ \ s -> (# s, x #)
94 fail s = error s -- not ioError?
96 liftIO :: IO a -> State# RealWorld -> STret RealWorld a
97 liftIO (IO m) = \s -> case m s of (# s', r #) -> STret s' r
99 bindIO :: IO a -> (a -> IO b) -> IO b
100 bindIO (IO m) k = IO ( \ s ->
102 (# new_s, a #) -> unIO (k a) new_s
108 %*********************************************************
110 \subsection{Coercions to @ST@}
112 %*********************************************************
116 /* Hugs doesn't distinguish these types so no coercion required) */
118 stToIO :: ST RealWorld a -> IO a
119 stToIO (ST m) = (IO m)
121 ioToST :: IO a -> ST RealWorld a
122 ioToST (IO m) = (ST m)
126 %*********************************************************
128 \subsection{Unsafe @IO@ operations}
130 %*********************************************************
134 {-# NOINLINE unsafePerformIO #-}
135 unsafePerformIO :: IO a -> a
136 unsafePerformIO (IO m) = case m realWorld# of (# _, r #) -> r
138 unsafeInterleaveIO :: IO a -> IO a
139 unsafeInterleaveIO = stToIO . unsafeInterleaveST . ioToST
143 %*********************************************************
145 \subsection{Type @IOError@}
147 %*********************************************************
149 A value @IOError@ encode errors occurred in the @IO@ monad.
150 An @IOError@ records a more specific error type, a descriptive
151 string and maybe the handle that was used when the error was
157 (Maybe Handle) -- the handle used by the action flagging the
159 IOErrorType -- what it was.
161 String -- error type specific information.
163 instance Eq IOError where
164 (IOError h1 e1 loc1 str1) == (IOError h2 e2 loc2 str2) =
165 e1==e2 && str1==str2 && h1==h2 && loc1 == loc2
168 = AlreadyExists | HardwareFault
169 | IllegalOperation | InappropriateType
170 | Interrupted | InvalidArgument
171 | NoSuchThing | OtherError
172 | PermissionDenied | ProtocolError
173 | ResourceBusy | ResourceExhausted
174 | ResourceVanished | SystemError
175 | TimeExpired | UnsatisfiedConstraints
176 | UnsupportedOperation | UserError
178 #if defined(cygwin32_TARGET_OS) || defined(mingw32_TARGET_OS)
179 | ComError Int -- HRESULT
183 instance Show IOErrorType where
187 AlreadyExists -> "already exists"
188 HardwareFault -> "hardware fault"
189 IllegalOperation -> "illegal operation"
190 InappropriateType -> "inappropriate type"
191 Interrupted -> "interrupted"
192 InvalidArgument -> "invalid argument"
193 NoSuchThing -> "does not exist"
194 OtherError -> "failed"
195 PermissionDenied -> "permission denied"
196 ProtocolError -> "protocol error"
197 ResourceBusy -> "resource busy"
198 ResourceExhausted -> "resource exhausted"
199 ResourceVanished -> "resource vanished"
200 SystemError -> "system error"
201 TimeExpired -> "timeout"
202 UnsatisfiedConstraints -> "unsatisified constraints" -- ultra-precise!
203 UserError -> "failed"
204 UnsupportedOperation -> "unsupported operation"
206 #if defined(cygwin32_TARGET_OS) || defined(mingw32_TARGET_OS)
207 ComError _ -> "COM error"
212 userError :: String -> IOError
213 userError str = IOError Nothing UserError "" str
216 Predicates on IOError; little effort made on these so far...
220 isAlreadyExistsError :: IOError -> Bool
221 isAlreadyExistsError (IOError _ AlreadyExists _ _) = True
222 isAlreadyExistsError _ = False
224 isAlreadyInUseError :: IOError -> Bool
225 isAlreadyInUseError (IOError _ ResourceBusy _ _) = True
226 isAlreadyInUseError _ = False
228 isFullError :: IOError -> Bool
229 isFullError (IOError _ ResourceExhausted _ _) = True
230 isFullError _ = False
232 isEOFError :: IOError -> Bool
233 isEOFError (IOError _ EOF _ _) = True
236 isIllegalOperation :: IOError -> Bool
237 isIllegalOperation (IOError _ IllegalOperation _ _) = True
238 isIllegalOperation _ = False
240 isPermissionError :: IOError -> Bool
241 isPermissionError (IOError _ PermissionDenied _ _) = True
242 isPermissionError _ = False
244 isDoesNotExistError :: IOError -> Bool
245 isDoesNotExistError (IOError _ NoSuchThing _ _) = True
246 isDoesNotExistError _ = False
248 isUserError :: IOError -> Bool
249 isUserError (IOError _ UserError _ _) = True
250 isUserError _ = False
257 -- For now we give a fairly uninformative error message which just happens to
258 -- be like the ones that Hugs used to give.
259 instance Show IOError where
260 showsPrec p (IOError hdl iot loc s) = showString s . showChar '\n'
262 instance Show IOError where
263 showsPrec p (IOError hdl iot loc s) =
268 _ -> showString "Action: " . showString loc . showChar '\n') .
272 _ -> showString "Reason: " . showString s)
277 Just h -> showString "Handle: " . showsPrec p h
282 The @String@ part of an @IOError@ is platform-dependent. However, to
283 provide a uniform mechanism for distinguishing among errors within
284 these broad categories, each platform-specific standard shall specify
285 the exact strings to be used for particular errors. For errors not
286 explicitly mentioned in the standard, any descriptive string may be
290 constructErrorAndFail :: String -> IO a
291 constructErrorAndFail call_site
292 = constructError call_site >>= \ io_error ->
295 constructErrorAndFailWithInfo :: String -> String -> IO a
296 constructErrorAndFailWithInfo call_site reason
297 = constructErrorMsg call_site (Just reason) >>= \ io_error ->
302 This doesn't seem to be documented/spelled out anywhere,
305 The implementation of the IO prelude uses various C stubs
306 to do the actual interaction with the OS. The bandwidth
307 \tr{C<->Haskell} is somewhat limited, so the general strategy
308 for flaggging any errors (apart from possibly using the
309 return code of the external call), is to set the @ghc_errtype@
310 to a value that is one of the \tr{#define}s in @includes/error.h@.
311 @ghc_errstr@ holds a character string providing error-specific
312 information. Error constructing functions will then reach out
313 and grab these values when generating
316 constructError :: String -> IO IOError
317 constructError call_site = constructErrorMsg call_site Nothing
319 constructErrorMsg :: String -> Maybe String -> IO IOError
320 constructErrorMsg call_site reason =
321 getErrType__ >>= \ errtype ->
322 getErrStr__ >>= \ str ->
325 case (errtype::Int) of
326 ERR_ALREADYEXISTS -> AlreadyExists
327 ERR_HARDWAREFAULT -> HardwareFault
328 ERR_ILLEGALOPERATION -> IllegalOperation
329 ERR_INAPPROPRIATETYPE -> InappropriateType
330 ERR_INTERRUPTED -> Interrupted
331 ERR_INVALIDARGUMENT -> InvalidArgument
332 ERR_NOSUCHTHING -> NoSuchThing
333 ERR_OTHERERROR -> OtherError
334 ERR_PERMISSIONDENIED -> PermissionDenied
335 ERR_PROTOCOLERROR -> ProtocolError
336 ERR_RESOURCEBUSY -> ResourceBusy
337 ERR_RESOURCEEXHAUSTED -> ResourceExhausted
338 ERR_RESOURCEVANISHED -> ResourceVanished
339 ERR_SYSTEMERROR -> SystemError
340 ERR_TIMEEXPIRED -> TimeExpired
341 ERR_UNSATISFIEDCONSTRAINTS -> UnsatisfiedConstraints
342 ERR_UNSUPPORTEDOPERATION -> UnsupportedOperation
349 OtherError -> "(error code: " ++ show errtype ++ ")"
355 return (IOError Nothing iot call_site msg)
358 File names are specified using @FilePath@, a OS-dependent
359 string that (hopefully, I guess) maps to an accessible file/object.
362 type FilePath = String
365 %*********************************************************
367 \subsection{Types @Handle@, @Handle__@}
369 %*********************************************************
371 The type for @Handle@ is defined rather than in @IOHandle@
372 module, as the @IOError@ type uses it..all operations over
373 a handles reside in @IOHandle@.
379 Sigh, the MVar ops in ConcBase depend on IO, the IO
380 representation here depend on MVars for handles (when
381 compiling in a concurrent way). Break the cycle by having
382 the definition of MVars go here:
385 data MVar a = MVar (MVar# RealWorld a)
387 -- pull in Eq (Mvar a) too, to avoid PrelConc being an orphan-instance module
388 instance Eq (MVar a) where
389 (MVar mvar1#) == (MVar mvar2#) = sameMVar# mvar1# mvar2#
392 Double sigh - ForeignObj is needed here too to break a cycle.
394 data ForeignObj = ForeignObj ForeignObj# -- another one
395 instance CCallable ForeignObj
397 eqForeignObj :: ForeignObj -> ForeignObj -> Bool
399 = unsafePerformIO (primEqForeignObj mp1 mp2) /= (0::Int)
401 foreign import "eqForeignObj" unsafe primEqForeignObj :: ForeignObj -> ForeignObj -> IO Int
403 instance Eq ForeignObj where
404 p == q = eqForeignObj p q
405 p /= q = not (eqForeignObj p q)
406 #endif /* ndef __HUGS__ */
408 #if defined(__CONCURRENT_HASKELL__)
409 newtype Handle = Handle (MVar Handle__)
411 newtype Handle = Handle (MutableVar RealWorld Handle__)
414 instance Eq Handle where
415 (Handle h1) == (Handle h2) = h1 == h2
418 A Handle is represented by (a reference to) a record
419 containing the state of the I/O port/device. We record
420 the following pieces of info:
422 * type (read,write,closed etc.)
423 * pointer to the external file object.
425 * user-friendly name (usually the
426 FilePath used when IO.openFile was called)
428 Note: when a Handle is garbage collected, we want to flush its buffer
429 and close the OS file handle, so as to free up a (precious) resource.
433 haFO__ :: FILE_OBJECT,
434 haType__ :: Handle__Type,
435 haBufferMode__ :: BufferMode,
436 haFilePath__ :: FilePath
440 Internally, we classify handles as being one
444 = ErrorHandle IOError
453 -- handle types are 'show'ed when printing error msgs, so
454 -- we provide a more user-friendly Show instance for it
455 -- than the derived one.
456 instance Show Handle__Type where
459 ErrorHandle iot -> showString "error " . showsPrec p iot
460 ClosedHandle -> showString "closed"
461 SemiClosedHandle -> showString "semi-closed"
462 ReadHandle -> showString "readable"
463 WriteHandle -> showString "writeable"
464 AppendHandle -> showString "writeable (append)"
465 ReadWriteHandle -> showString "read-writeable"
467 instance Show Handle where
468 showsPrec p (Handle h) =
470 #if defined(__CONCURRENT_HASKELL__)
472 hdl_ = unsafePerformIO (primTakeMVar h)
474 -- (Big) SIGH: unfolded defn of takeMVar to avoid
475 -- an (oh-so) unfortunate module loop with PrelConc.
476 hdl_ = unsafePerformIO (IO $ \ s# ->
477 case h of { MVar h# ->
478 case takeMVar# h# s# of { (# s2# , r #) ->
482 hdl_ = unsafePerformIO (stToIO (readVar h))
486 showHdl (haType__ hdl_)
487 (showString "loc=" . showString (haFilePath__ hdl_) . showChar ',' .
488 showString "type=" . showsPrec p (haType__ hdl_) . showChar ',' .
489 showString "buffering=" . showBufMode (haFO__ hdl_) (haBufferMode__ hdl_) . showString "}\n" )
491 showHdl :: Handle__Type -> ShowS -> ShowS
494 ClosedHandle -> showsPrec p ht . showString "}\n"
495 ErrorHandle _ -> showsPrec p ht . showString "}\n"
498 showBufMode :: FILE_OBJECT -> BufferMode -> ShowS
501 NoBuffering -> showString "none"
502 LineBuffering -> showString "line"
503 BlockBuffering (Just n) -> showString "block " . showParen True (showsPrec p n)
504 BlockBuffering Nothing -> showString "block " . showParen True (showsPrec p def)
507 def = unsafePerformIO (getBufSize fo)
509 mkBuffer__ :: FILE_OBJECT -> Int -> IO ()
510 mkBuffer__ fo sz_in_bytes = do
513 0 -> return nullAddr -- this has the effect of overwriting the pointer to the old buffer.
515 chunk <- allocMemory__ sz_in_bytes
517 then ioError (IOError Nothing ResourceExhausted "mkBuffer__" "not enough virtual memory")
519 setBuf fo chunk sz_in_bytes
523 %*********************************************************
525 \subsection[BufferMode]{Buffering modes}
527 %*********************************************************
529 Three kinds of buffering are supported: line-buffering,
530 block-buffering or no-buffering. These modes have the following
531 effects. For output, items are written out from the internal
532 buffer according to the buffer mode:
535 \item[line-buffering] the entire output buffer is written
536 out whenever a newline is output, the output buffer overflows,
537 a flush is issued, or the handle is closed.
539 \item[block-buffering] the entire output buffer is written out whenever
540 it overflows, a flush is issued, or the handle
543 \item[no-buffering] output is written immediately, and never stored
544 in the output buffer.
547 The output buffer is emptied as soon as it has been written out.
549 Similarly, input occurs according to the buffer mode for handle {\em hdl}.
551 \item[line-buffering] when the input buffer for {\em hdl} is not empty,
552 the next item is obtained from the buffer;
553 otherwise, when the input buffer is empty,
554 characters up to and including the next newline
555 character are read into the buffer. No characters
556 are available until the newline character is
558 \item[block-buffering] when the input buffer for {\em hdl} becomes empty,
559 the next block of data is read into this buffer.
560 \item[no-buffering] the next input item is read and returned.
563 For most implementations, physical files will normally be block-buffered
564 and terminals will normally be line-buffered. (the IO interface provides
565 operations for changing the default buffering of a handle tho.)
569 = NoBuffering | LineBuffering | BlockBuffering (Maybe Int)
570 deriving (Eq, Ord, Show)
571 {- Read instance defined in IO. -}
575 Foreign import declarations to helper routines:
578 foreign import "libHS_cbits" "getErrStr__" unsafe getErrStr__ :: IO Addr
579 foreign import "libHS_cbits" "getErrNo__" unsafe getErrNo__ :: IO Int
580 foreign import "libHS_cbits" "getErrType__" unsafe getErrType__ :: IO Int
582 foreign import "libHS_cbits" "allocMemory__" unsafe
583 allocMemory__ :: Int -> IO Addr
584 foreign import "libHS_cbits" "getBufSize" unsafe
585 getBufSize :: FILE_OBJECT -> IO Int
586 foreign import "libHS_cbits" "setBuf" unsafe
587 setBuf :: FILE_OBJECT -> Addr -> Int -> IO ()