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
35 alreadyExistsErrorType, -- :: IOErrorType
36 doesNotExistErrorType,
37 alreadyInUseErrorType,
40 illegalOperationErrorType,
44 isAlreadyExistsErrorType, -- :: IOErrorType -> Bool
45 isDoesNotExistErrorType,
46 isAlreadyInUseErrorType,
49 isIllegalOperationErrorType,
50 isPermissionErrorType,
53 isAlreadyExistsError, -- :: IOError -> Bool
63 ioeGetErrorType, -- :: IOError -> IOErrorType
65 ioeGetErrorString, -- :: IOError -> String
66 ioeGetHandle, -- :: IOError -> Maybe Handle
67 ioeGetFileName, -- :: IOError -> Maybe FilePath
74 #ifdef __GLASGOW_HASKELL__
82 import Hugs.Prelude(Handle, IOException(..), IOErrorType(..))
91 , isAlreadyExistsError -- :: IOError -> Bool
99 , ioeGetErrorString -- :: IOError -> String
100 , ioeGetHandle -- :: IOError -> Maybe Handle
101 , ioeGetFileName -- :: IOError -> Maybe FilePath
103 --import Data.Maybe (fromJust)
104 --import Control.Monad (MonadPlus(mplus))
107 -- | The construct @try comp@ exposes IO errors which occur within a
108 -- computation, and which are not fully handled.
109 -- Other exceptions are not caught by this variant;
110 -- to catch all exceptions, use @try@ from "Control.Exception".
113 try :: IO a -> IO (Either IOError a)
114 try f = catch (do r <- f
119 #if defined(__GLASGOW_HASKELL__) || defined(__HUGS__)
120 -- -----------------------------------------------------------------------------
121 -- Constructing an IOError
123 mkIOError :: IOErrorType -> String -> Maybe Handle -> Maybe FilePath -> IOError
124 mkIOError t location maybe_hdl maybe_filename =
125 IOError{ ioe_type = t,
126 ioe_location = location,
127 ioe_description = "",
128 ioe_handle = maybe_hdl,
129 ioe_filename = maybe_filename
132 mkIOError EOF location maybe_hdl maybe_filename =
133 EOFError location (fromJust maybe_hdl)
134 mkIOError UserError location maybe_hdl maybe_filename =
135 UserError location ""
136 mkIOError t location maybe_hdl maybe_filename =
137 NHC.FFI.mkIOError location maybe_filename maybe_handle (ioeTypeToInt t)
139 ioeTypeToInt AlreadyExists = fromEnum EEXIST
140 ioeTypeToInt NoSuchThing = fromEnum ENOENT
141 ioeTypeToInt ResourceBusy = fromEnum EBUSY
142 ioeTypeToInt ResourceExhausted = fromEnum ENOSPC
143 ioeTypeToInt IllegalOperation = fromEnum EPERM
144 ioeTypeToInt PermissionDenied = fromEnum EACCES
146 #endif /* __GLASGOW_HASKELL__ || __HUGS__ */
149 -- -----------------------------------------------------------------------------
152 isAlreadyExistsError, isDoesNotExistError, isAlreadyInUseError,
153 isFullError, isEOFError, isIllegalOperation, isPermissionError,
154 isUserError :: IOError -> Bool
156 isAlreadyExistsError = isAlreadyExistsErrorType . ioeGetErrorType
157 isDoesNotExistError = isDoesNotExistErrorType . ioeGetErrorType
158 isAlreadyInUseError = isAlreadyInUseErrorType . ioeGetErrorType
159 isFullError = isFullErrorType . ioeGetErrorType
160 isEOFError = isEOFErrorType . ioeGetErrorType
161 isIllegalOperation = isIllegalOperationErrorType . ioeGetErrorType
162 isPermissionError = isPermissionErrorType . ioeGetErrorType
163 isUserError = isUserErrorType . ioeGetErrorType
166 -- -----------------------------------------------------------------------------
170 data IOErrorType = AlreadyExists | NoSuchThing | ResourceBusy
171 | ResourceExhausted | EOF | IllegalOperation
172 | PermissionDenied | UserError
175 alreadyExistsErrorType, doesNotExistErrorType, alreadyInUseErrorType,
176 fullErrorType, eofErrorType, illegalOperationErrorType,
177 permissionErrorType, userErrorType :: IOErrorType
179 alreadyExistsErrorType = AlreadyExists
180 doesNotExistErrorType = NoSuchThing
181 alreadyInUseErrorType = ResourceBusy
182 fullErrorType = ResourceExhausted
184 illegalOperationErrorType = IllegalOperation
185 permissionErrorType = PermissionDenied
186 userErrorType = UserError
188 -- -----------------------------------------------------------------------------
189 -- IOErrorType predicates
191 isAlreadyExistsErrorType, isDoesNotExistErrorType, isAlreadyInUseErrorType,
192 isFullErrorType, isEOFErrorType, isIllegalOperationErrorType,
193 isPermissionErrorType, isUserErrorType :: IOErrorType -> Bool
195 isAlreadyExistsErrorType AlreadyExists = True
196 isAlreadyExistsErrorType _ = False
198 isDoesNotExistErrorType NoSuchThing = True
199 isDoesNotExistErrorType _ = False
201 isAlreadyInUseErrorType ResourceBusy = True
202 isAlreadyInUseErrorType _ = False
204 isFullErrorType ResourceExhausted = True
205 isFullErrorType _ = False
207 isEOFErrorType EOF = True
208 isEOFErrorType _ = False
210 isIllegalOperationErrorType IllegalOperation = True
211 isIllegalOperationErrorType _ = False
213 isPermissionErrorType PermissionDenied = True
214 isPermissionErrorType _ = False
216 isUserErrorType UserError = True
217 isUserErrorType _ = False
219 -- -----------------------------------------------------------------------------
222 #if defined(__GLASGOW_HASKELL__) || defined(__HUGS__)
223 ioeGetErrorType :: IOError -> IOErrorType
224 ioeGetHandle :: IOError -> Maybe Handle
225 ioeGetErrorString :: IOError -> String
226 ioeGetFileName :: IOError -> Maybe FilePath
228 ioeGetErrorType ioe = ioe_type ioe
230 ioeGetHandle ioe = ioe_handle ioe
232 ioeGetErrorString ioe
233 | isUserErrorType (ioe_type ioe) = ioe_description ioe
234 | otherwise = show (ioe_type ioe)
236 ioeGetFileName ioe = ioe_filename ioe
238 -- -----------------------------------------------------------------------------
239 -- annotating an IOError
241 annotateIOError :: IOError
246 annotateIOError (IOError hdl errTy _ str path) loc ohdl opath =
247 IOError (hdl `mplus` ohdl) errTy loc str (path `mplus` opath)
249 Nothing `mplus` ys = ys
251 #endif /* __GLASGOW_HASKELL__ || __HUGS__ */
254 annotateIOError (IOError msg file hdl code) msg' file' hdl' =
255 IOError (msg++'\n':msg') (file`mplus`file') (hdl`mplus`hdl') code
256 annotateIOError (EOFError msg hdl) msg' file' hdl' =
257 EOFError (msg++'\n':msg') (hdl`mplus`hdl')
258 annotateIOError (UserError loc msg) msg' file' hdl' =
259 UserError loc (msg++'\n':msg')
260 annotateIOError (PatternError loc) msg' file' hdl' =
261 PatternError (loc++'\n':msg')