1 {-# OPTIONS -fno-implicit-prelude #-}
3 -----------------------------------------------------------------------------
5 -- Module : System.IO.Error
6 -- Copyright : (c) The University of Glasgow 2001
7 -- License : BSD-style (see the file libraries/base/LICENSE)
9 -- Maintainer : libraries@haskell.org
10 -- Stability : provisional
11 -- Portability : portable
13 -- Standard IO Errors.
15 -----------------------------------------------------------------------------
17 module System.IO.Error (
19 IOErrorType, -- abstract
21 catch, -- :: IO a -> (IOError -> IO a) -> IO a
22 try, -- :: IO a -> IO (Either IOError a)
24 ioError, -- :: IOError -> IO a
25 userError, -- :: String -> IOError
28 mkIOError, -- :: IOErrorType -> String -> Maybe Handle
29 -- -> Maybe FilePath -> IOError
31 annotateIOError, -- :: IOError -> String -> Maybe Handle
32 -- -> Maybe FilePath -> IOError
34 modifyIOError, -- :: (IOError -> IOError) -> IO a -> IO a
37 alreadyExistsErrorType, -- :: IOErrorType
38 doesNotExistErrorType,
39 alreadyInUseErrorType,
42 illegalOperationErrorType,
46 isAlreadyExistsErrorType, -- :: IOErrorType -> Bool
47 isDoesNotExistErrorType,
48 isAlreadyInUseErrorType,
51 isIllegalOperationErrorType,
52 isPermissionErrorType,
55 isAlreadyExistsError, -- :: IOError -> Bool
65 ioeGetErrorType, -- :: IOError -> IOErrorType
67 ioeGetErrorString, -- :: IOError -> String
68 ioeGetHandle, -- :: IOError -> Maybe Handle
69 ioeGetFileName, -- :: IOError -> Maybe FilePath
72 ioeSetErrorType, -- :: IOError -> IOErrorType -> IOError
73 ioeSetErrorString, -- :: IOError -> String -> IOError
74 ioeSetHandle, -- :: IOError -> Handle -> IOError
75 ioeSetFileName, -- :: IOError -> FilePath -> IOError
82 #ifdef __GLASGOW_HASKELL__
90 import Hugs.Prelude(Handle, IOException(..), IOErrorType(..))
99 , isAlreadyExistsError -- :: IOError -> Bool
100 , isDoesNotExistError
101 , isAlreadyInUseError
107 , ioeGetErrorString -- :: IOError -> String
108 , ioeGetHandle -- :: IOError -> Maybe Handle
109 , ioeGetFileName -- :: IOError -> Maybe FilePath
111 --import Data.Maybe (fromJust)
112 --import Control.Monad (MonadPlus(mplus))
115 -- | The construct @try comp@ exposes IO errors which occur within a
116 -- computation, and which are not fully handled.
117 -- Other exceptions are not caught by this variant;
118 -- to catch all exceptions, use @try@ from "Control.Exception".
121 try :: IO a -> IO (Either IOError a)
122 try f = catch (do r <- f
127 #if defined(__GLASGOW_HASKELL__) || defined(__HUGS__)
128 -- -----------------------------------------------------------------------------
129 -- Constructing an IOError
131 mkIOError :: IOErrorType -> String -> Maybe Handle -> Maybe FilePath -> IOError
132 mkIOError t location maybe_hdl maybe_filename =
133 IOError{ ioe_type = t,
134 ioe_location = location,
135 ioe_description = "",
136 ioe_handle = maybe_hdl,
137 ioe_filename = maybe_filename
140 mkIOError EOF location maybe_hdl maybe_filename =
141 EOFError location (fromJust maybe_hdl)
142 mkIOError UserError location maybe_hdl maybe_filename =
143 UserError location ""
144 mkIOError t location maybe_hdl maybe_filename =
145 NHC.FFI.mkIOError location maybe_filename maybe_handle (ioeTypeToInt t)
147 ioeTypeToInt AlreadyExists = fromEnum EEXIST
148 ioeTypeToInt NoSuchThing = fromEnum ENOENT
149 ioeTypeToInt ResourceBusy = fromEnum EBUSY
150 ioeTypeToInt ResourceExhausted = fromEnum ENOSPC
151 ioeTypeToInt IllegalOperation = fromEnum EPERM
152 ioeTypeToInt PermissionDenied = fromEnum EACCES
154 #endif /* __GLASGOW_HASKELL__ || __HUGS__ */
157 -- -----------------------------------------------------------------------------
160 isAlreadyExistsError, isDoesNotExistError, isAlreadyInUseError,
161 isFullError, isEOFError, isIllegalOperation, isPermissionError,
162 isUserError :: IOError -> Bool
164 isAlreadyExistsError = isAlreadyExistsErrorType . ioeGetErrorType
165 isDoesNotExistError = isDoesNotExistErrorType . ioeGetErrorType
166 isAlreadyInUseError = isAlreadyInUseErrorType . ioeGetErrorType
167 isFullError = isFullErrorType . ioeGetErrorType
168 isEOFError = isEOFErrorType . ioeGetErrorType
169 isIllegalOperation = isIllegalOperationErrorType . ioeGetErrorType
170 isPermissionError = isPermissionErrorType . ioeGetErrorType
171 isUserError = isUserErrorType . ioeGetErrorType
174 -- -----------------------------------------------------------------------------
178 data IOErrorType = AlreadyExists | NoSuchThing | ResourceBusy
179 | ResourceExhausted | EOF | IllegalOperation
180 | PermissionDenied | UserError
183 alreadyExistsErrorType, doesNotExistErrorType, alreadyInUseErrorType,
184 fullErrorType, eofErrorType, illegalOperationErrorType,
185 permissionErrorType, userErrorType :: IOErrorType
187 alreadyExistsErrorType = AlreadyExists
188 doesNotExistErrorType = NoSuchThing
189 alreadyInUseErrorType = ResourceBusy
190 fullErrorType = ResourceExhausted
192 illegalOperationErrorType = IllegalOperation
193 permissionErrorType = PermissionDenied
194 userErrorType = UserError
196 -- -----------------------------------------------------------------------------
197 -- IOErrorType predicates
199 isAlreadyExistsErrorType, isDoesNotExistErrorType, isAlreadyInUseErrorType,
200 isFullErrorType, isEOFErrorType, isIllegalOperationErrorType,
201 isPermissionErrorType, isUserErrorType :: IOErrorType -> Bool
203 isAlreadyExistsErrorType AlreadyExists = True
204 isAlreadyExistsErrorType _ = False
206 isDoesNotExistErrorType NoSuchThing = True
207 isDoesNotExistErrorType _ = False
209 isAlreadyInUseErrorType ResourceBusy = True
210 isAlreadyInUseErrorType _ = False
212 isFullErrorType ResourceExhausted = True
213 isFullErrorType _ = False
215 isEOFErrorType EOF = True
216 isEOFErrorType _ = False
218 isIllegalOperationErrorType IllegalOperation = True
219 isIllegalOperationErrorType _ = False
221 isPermissionErrorType PermissionDenied = True
222 isPermissionErrorType _ = False
224 isUserErrorType UserError = True
225 isUserErrorType _ = False
227 -- -----------------------------------------------------------------------------
230 #if defined(__GLASGOW_HASKELL__) || defined(__HUGS__)
231 ioeGetErrorType :: IOError -> IOErrorType
232 ioeGetErrorString :: IOError -> String
233 ioeGetHandle :: IOError -> Maybe Handle
234 ioeGetFileName :: IOError -> Maybe FilePath
236 ioeGetErrorType ioe = ioe_type ioe
238 ioeGetErrorString ioe
239 | isUserErrorType (ioe_type ioe) = ioe_description ioe
240 | otherwise = show (ioe_type ioe)
242 ioeGetHandle ioe = ioe_handle ioe
244 ioeGetFileName ioe = ioe_filename ioe
246 ioeSetErrorType :: IOError -> IOErrorType -> IOError
247 ioeSetErrorString :: IOError -> String -> IOError
248 ioeSetHandle :: IOError -> Handle -> IOError
249 ioeSetFileName :: IOError -> FilePath -> IOError
251 ioeSetErrorType ioe errtype = ioe{ ioe_type = errtype }
252 ioeSetErrorString ioe str = ioe{ ioe_description = str }
253 ioeSetHandle ioe hdl = ioe{ ioe_handle = Just hdl }
254 ioeSetFileName ioe filename = ioe{ ioe_filename = Just filename }
256 modifyIOError :: (IOError -> IOError) -> IO a -> IO a
257 modifyIOError f io = catch io (\e -> ioError (f e))
259 -- -----------------------------------------------------------------------------
260 -- annotating an IOError
262 annotateIOError :: IOError
267 annotateIOError (IOError ohdl errTy _ str opath) loc hdl path =
268 IOError (hdl `mplus` ohdl) errTy loc str (path `mplus` opath)
270 Nothing `mplus` ys = ys
272 #endif /* __GLASGOW_HASKELL__ || __HUGS__ */
275 annotateIOError (IOError msg file hdl code) msg' file' hdl' =
276 IOError (msg++'\n':msg') (file`mplus`file') (hdl`mplus`hdl') code
277 annotateIOError (EOFError msg hdl) msg' file' hdl' =
278 EOFError (msg++'\n':msg') (hdl`mplus`hdl')
279 annotateIOError (UserError loc msg) msg' file' hdl' =
280 UserError loc (msg++'\n':msg')
281 annotateIOError (PatternError loc) msg' file' hdl' =
282 PatternError (loc++'\n':msg')