a908f0f8069e56d8b3511a0f1267703072fc09e0
[ghc-base.git] / Foreign / C / Error.hs
1 {-# OPTIONS -fno-implicit-prelude -#include "HsBase.h" #-}
2 -----------------------------------------------------------------------------
3 -- 
4 -- Module      :  Foreign.C.Error
5 -- Copyright   :  (c) The FFI task force 2001
6 -- License     :  BSD-style (see the file libraries/core/LICENSE)
7 -- 
8 -- Maintainer  :  ffi@haskell.org
9 -- Stability   :  provisional
10 -- Portability :  portable
11 --
12 -- $Id: Error.hs,v 1.6 2002/02/07 11:13:30 simonmar Exp $
13 --
14 -- C-specific Marshalling support: Handling of C "errno" error codes
15 --
16 -----------------------------------------------------------------------------
17
18 module Foreign.C.Error (
19
20   -- Haskell representation for "errno" values
21   --
22   Errno(..),            -- instance: Eq
23   eOK, e2BIG, eACCES, eADDRINUSE, eADDRNOTAVAIL, eADV, eAFNOSUPPORT, eAGAIN, 
24   eALREADY, eBADF, eBADMSG, eBADRPC, eBUSY, eCHILD, eCOMM, eCONNABORTED, 
25   eCONNREFUSED, eCONNRESET, eDEADLK, eDESTADDRREQ, eDIRTY, eDOM, eDQUOT, 
26   eEXIST, eFAULT, eFBIG, eFTYPE, eHOSTDOWN, eHOSTUNREACH, eIDRM, eILSEQ, 
27   eINPROGRESS, eINTR, eINVAL, eIO, eISCONN, eISDIR, eLOOP, eMFILE, eMLINK, 
28   eMSGSIZE, eMULTIHOP, eNAMETOOLONG, eNETDOWN, eNETRESET, eNETUNREACH, 
29   eNFILE, eNOBUFS, eNODATA, eNODEV, eNOENT, eNOEXEC, eNOLCK, eNOLINK, 
30   eNOMEM, eNOMSG, eNONET, eNOPROTOOPT, eNOSPC, eNOSR, eNOSTR, eNOSYS, 
31   eNOTBLK, eNOTCONN, eNOTDIR, eNOTEMPTY, eNOTSOCK, eNOTTY, eNXIO, 
32   eOPNOTSUPP, ePERM, ePFNOSUPPORT, ePIPE, ePROCLIM, ePROCUNAVAIL, 
33   ePROGMISMATCH, ePROGUNAVAIL, ePROTO, ePROTONOSUPPORT, ePROTOTYPE, 
34   eRANGE, eREMCHG, eREMOTE, eROFS, eRPCMISMATCH, eRREMOTE, eSHUTDOWN, 
35   eSOCKTNOSUPPORT, eSPIPE, eSRCH, eSRMNT, eSTALE, eTIME, eTIMEDOUT, 
36   eTOOMANYREFS, eTXTBSY, eUSERS, eWOULDBLOCK, eXDEV,
37                         -- :: Errno
38   isValidErrno,         -- :: Errno -> Bool
39
40   -- access to the current thread's "errno" value
41   --
42   getErrno,             -- :: IO Errno
43   resetErrno,           -- :: IO ()
44
45   -- conversion of an "errno" value into IO error
46   --
47   errnoToIOError,       -- :: String       -- location
48                         -- -> Errno        -- errno
49                         -- -> Maybe Handle -- handle
50                         -- -> Maybe String -- filename
51                         -- -> IOError
52
53   -- throw current "errno" value
54   --
55   throwErrno,           -- ::                String               -> IO a
56
57   -- guards for IO operations that may fail
58   --
59   throwErrnoIf,         -- :: (a -> Bool) -> String -> IO a       -> IO a
60   throwErrnoIf_,        -- :: (a -> Bool) -> String -> IO a       -> IO ()
61   throwErrnoIfRetry,    -- :: (a -> Bool) -> String -> IO a       -> IO a
62   throwErrnoIfRetry_,   -- :: (a -> Bool) -> String -> IO a       -> IO ()
63   throwErrnoIfMinus1,   -- :: Num a 
64                         -- =>                String -> IO a       -> IO a
65   throwErrnoIfMinus1_,  -- :: Num a 
66                         -- =>                String -> IO a       -> IO ()
67   throwErrnoIfMinus1Retry,  
68                         -- :: Num a 
69                         -- =>                String -> IO a       -> IO a
70   throwErrnoIfMinus1Retry_,  
71                         -- :: Num a 
72                         -- =>                String -> IO a       -> IO ()
73   throwErrnoIfNull,     -- ::                String -> IO (Ptr a) -> IO (Ptr a)
74   throwErrnoIfNullRetry,-- ::                String -> IO (Ptr a) -> IO (Ptr a)
75
76   throwErrnoIfRetryMayBlock, 
77   throwErrnoIfRetryMayBlock_,
78   throwErrnoIfMinus1RetryMayBlock,
79   throwErrnoIfMinus1RetryMayBlock_,  
80   throwErrnoIfNullRetryMayBlock
81 ) where
82
83
84 -- this is were we get the CCONST_XXX definitions from that configure
85 -- calculated for us
86 --
87 #include "config.h"
88
89 -- system dependent imports
90 -- ------------------------
91
92 -- GHC allows us to get at the guts inside IO errors/exceptions
93 --
94 #if __GLASGOW_HASKELL__
95 import GHC.IOBase (Exception(..), IOException(..), IOErrorType(..))
96 #endif /* __GLASGOW_HASKELL__ */
97
98
99 -- regular imports
100 -- ---------------
101
102 import Foreign.Ptr
103 import Foreign.C.Types
104 import Foreign.C.String
105 import Foreign.Marshal.Error    ( void )
106 import Data.Maybe
107
108 #if __GLASGOW_HASKELL__
109 import GHC.Storable
110 import GHC.IOBase
111 import GHC.Num
112 import GHC.Base
113 #else
114 import System.IO                ( IOError, Handle, ioError )
115 #endif
116
117 -- "errno" type
118 -- ------------
119
120 -- import of C function that gives address of errno
121 -- This function exists because errno is a variable on some systems, but on
122 -- Windows it is a macro for a function...
123 -- [yes, global variables and thread safety don't really go hand-in-hand. -- sof]
124 foreign import ccall unsafe "ghcErrno" _errno :: Ptr CInt
125
126 -- Haskell representation for "errno" values
127 --
128 newtype Errno = Errno CInt
129
130 instance Eq Errno where
131   errno1@(Errno no1) == errno2@(Errno no2) 
132     | isValidErrno errno1 && isValidErrno errno2 = no1 == no2
133     | otherwise                                  = False
134
135 -- common "errno" symbols
136 --
137 eOK, e2BIG, eACCES, eADDRINUSE, eADDRNOTAVAIL, eADV, eAFNOSUPPORT, eAGAIN, 
138   eALREADY, eBADF, eBADMSG, eBADRPC, eBUSY, eCHILD, eCOMM, eCONNABORTED, 
139   eCONNREFUSED, eCONNRESET, eDEADLK, eDESTADDRREQ, eDIRTY, eDOM, eDQUOT, 
140   eEXIST, eFAULT, eFBIG, eFTYPE, eHOSTDOWN, eHOSTUNREACH, eIDRM, eILSEQ, 
141   eINPROGRESS, eINTR, eINVAL, eIO, eISCONN, eISDIR, eLOOP, eMFILE, eMLINK, 
142   eMSGSIZE, eMULTIHOP, eNAMETOOLONG, eNETDOWN, eNETRESET, eNETUNREACH, 
143   eNFILE, eNOBUFS, eNODATA, eNODEV, eNOENT, eNOEXEC, eNOLCK, eNOLINK, 
144   eNOMEM, eNOMSG, eNONET, eNOPROTOOPT, eNOSPC, eNOSR, eNOSTR, eNOSYS, 
145   eNOTBLK, eNOTCONN, eNOTDIR, eNOTEMPTY, eNOTSOCK, eNOTTY, eNXIO, 
146   eOPNOTSUPP, ePERM, ePFNOSUPPORT, ePIPE, ePROCLIM, ePROCUNAVAIL, 
147   ePROGMISMATCH, ePROGUNAVAIL, ePROTO, ePROTONOSUPPORT, ePROTOTYPE, 
148   eRANGE, eREMCHG, eREMOTE, eROFS, eRPCMISMATCH, eRREMOTE, eSHUTDOWN, 
149   eSOCKTNOSUPPORT, eSPIPE, eSRCH, eSRMNT, eSTALE, eTIME, eTIMEDOUT, 
150   eTOOMANYREFS, eTXTBSY, eUSERS, eWOULDBLOCK, eXDEV                    :: Errno
151 --
152 -- the cCONST_XXX identifiers are cpp symbols whose value is computed by
153 -- configure 
154 --
155 eOK             = Errno 0
156 e2BIG           = Errno (cCONST_E2BIG)
157 eACCES          = Errno (cCONST_EACCES)
158 eADDRINUSE      = Errno (cCONST_EADDRINUSE)
159 eADDRNOTAVAIL   = Errno (cCONST_EADDRNOTAVAIL)
160 eADV            = Errno (cCONST_EADV)
161 eAFNOSUPPORT    = Errno (cCONST_EAFNOSUPPORT)
162 eAGAIN          = Errno (cCONST_EAGAIN)
163 eALREADY        = Errno (cCONST_EALREADY)
164 eBADF           = Errno (cCONST_EBADF)
165 eBADMSG         = Errno (cCONST_EBADMSG)
166 eBADRPC         = Errno (cCONST_EBADRPC)
167 eBUSY           = Errno (cCONST_EBUSY)
168 eCHILD          = Errno (cCONST_ECHILD)
169 eCOMM           = Errno (cCONST_ECOMM)
170 eCONNABORTED    = Errno (cCONST_ECONNABORTED)
171 eCONNREFUSED    = Errno (cCONST_ECONNREFUSED)
172 eCONNRESET      = Errno (cCONST_ECONNRESET)
173 eDEADLK         = Errno (cCONST_EDEADLK)
174 eDESTADDRREQ    = Errno (cCONST_EDESTADDRREQ)
175 eDIRTY          = Errno (cCONST_EDIRTY)
176 eDOM            = Errno (cCONST_EDOM)
177 eDQUOT          = Errno (cCONST_EDQUOT)
178 eEXIST          = Errno (cCONST_EEXIST)
179 eFAULT          = Errno (cCONST_EFAULT)
180 eFBIG           = Errno (cCONST_EFBIG)
181 eFTYPE          = Errno (cCONST_EFTYPE)
182 eHOSTDOWN       = Errno (cCONST_EHOSTDOWN)
183 eHOSTUNREACH    = Errno (cCONST_EHOSTUNREACH)
184 eIDRM           = Errno (cCONST_EIDRM)
185 eILSEQ          = Errno (cCONST_EILSEQ)
186 eINPROGRESS     = Errno (cCONST_EINPROGRESS)
187 eINTR           = Errno (cCONST_EINTR)
188 eINVAL          = Errno (cCONST_EINVAL)
189 eIO             = Errno (cCONST_EIO)
190 eISCONN         = Errno (cCONST_EISCONN)
191 eISDIR          = Errno (cCONST_EISDIR)
192 eLOOP           = Errno (cCONST_ELOOP)
193 eMFILE          = Errno (cCONST_EMFILE)
194 eMLINK          = Errno (cCONST_EMLINK)
195 eMSGSIZE        = Errno (cCONST_EMSGSIZE)
196 eMULTIHOP       = Errno (cCONST_EMULTIHOP)
197 eNAMETOOLONG    = Errno (cCONST_ENAMETOOLONG)
198 eNETDOWN        = Errno (cCONST_ENETDOWN)
199 eNETRESET       = Errno (cCONST_ENETRESET)
200 eNETUNREACH     = Errno (cCONST_ENETUNREACH)
201 eNFILE          = Errno (cCONST_ENFILE)
202 eNOBUFS         = Errno (cCONST_ENOBUFS)
203 eNODATA         = Errno (cCONST_ENODATA)
204 eNODEV          = Errno (cCONST_ENODEV)
205 eNOENT          = Errno (cCONST_ENOENT)
206 eNOEXEC         = Errno (cCONST_ENOEXEC)
207 eNOLCK          = Errno (cCONST_ENOLCK)
208 eNOLINK         = Errno (cCONST_ENOLINK)
209 eNOMEM          = Errno (cCONST_ENOMEM)
210 eNOMSG          = Errno (cCONST_ENOMSG)
211 eNONET          = Errno (cCONST_ENONET)
212 eNOPROTOOPT     = Errno (cCONST_ENOPROTOOPT)
213 eNOSPC          = Errno (cCONST_ENOSPC)
214 eNOSR           = Errno (cCONST_ENOSR)
215 eNOSTR          = Errno (cCONST_ENOSTR)
216 eNOSYS          = Errno (cCONST_ENOSYS)
217 eNOTBLK         = Errno (cCONST_ENOTBLK)
218 eNOTCONN        = Errno (cCONST_ENOTCONN)
219 eNOTDIR         = Errno (cCONST_ENOTDIR)
220 eNOTEMPTY       = Errno (cCONST_ENOTEMPTY)
221 eNOTSOCK        = Errno (cCONST_ENOTSOCK)
222 eNOTTY          = Errno (cCONST_ENOTTY)
223 eNXIO           = Errno (cCONST_ENXIO)
224 eOPNOTSUPP      = Errno (cCONST_EOPNOTSUPP)
225 ePERM           = Errno (cCONST_EPERM)
226 ePFNOSUPPORT    = Errno (cCONST_EPFNOSUPPORT)
227 ePIPE           = Errno (cCONST_EPIPE)
228 ePROCLIM        = Errno (cCONST_EPROCLIM)
229 ePROCUNAVAIL    = Errno (cCONST_EPROCUNAVAIL)
230 ePROGMISMATCH   = Errno (cCONST_EPROGMISMATCH)
231 ePROGUNAVAIL    = Errno (cCONST_EPROGUNAVAIL)
232 ePROTO          = Errno (cCONST_EPROTO)
233 ePROTONOSUPPORT = Errno (cCONST_EPROTONOSUPPORT)
234 ePROTOTYPE      = Errno (cCONST_EPROTOTYPE)
235 eRANGE          = Errno (cCONST_ERANGE)
236 eREMCHG         = Errno (cCONST_EREMCHG)
237 eREMOTE         = Errno (cCONST_EREMOTE)
238 eROFS           = Errno (cCONST_EROFS)
239 eRPCMISMATCH    = Errno (cCONST_ERPCMISMATCH)
240 eRREMOTE        = Errno (cCONST_ERREMOTE)
241 eSHUTDOWN       = Errno (cCONST_ESHUTDOWN)
242 eSOCKTNOSUPPORT = Errno (cCONST_ESOCKTNOSUPPORT)
243 eSPIPE          = Errno (cCONST_ESPIPE)
244 eSRCH           = Errno (cCONST_ESRCH)
245 eSRMNT          = Errno (cCONST_ESRMNT)
246 eSTALE          = Errno (cCONST_ESTALE)
247 eTIME           = Errno (cCONST_ETIME)
248 eTIMEDOUT       = Errno (cCONST_ETIMEDOUT)
249 eTOOMANYREFS    = Errno (cCONST_ETOOMANYREFS)
250 eTXTBSY         = Errno (cCONST_ETXTBSY)
251 eUSERS          = Errno (cCONST_EUSERS)
252 eWOULDBLOCK     = Errno (cCONST_EWOULDBLOCK)
253 eXDEV           = Errno (cCONST_EXDEV)
254
255 -- checks whether the given errno value is supported on the current
256 -- architecture
257 --
258 isValidErrno               :: Errno -> Bool
259 --
260 -- the configure script sets all invalid "errno"s to -1
261 --
262 isValidErrno (Errno errno)  = errno /= -1
263
264
265 -- access to the current thread's "errno" value
266 -- --------------------------------------------
267
268 -- yield the current thread's "errno" value
269 --
270 getErrno :: IO Errno
271 getErrno  = do e <- peek _errno; return (Errno e)
272
273 -- set the current thread's "errno" value to 0
274 --
275 resetErrno :: IO ()
276 resetErrno  = poke _errno 0
277
278
279 -- throw current "errno" value
280 -- ---------------------------
281
282 -- the common case: throw an IO error based on a textual description
283 -- of the error location and the current thread's "errno" value
284 --
285 throwErrno     :: String -> IO a
286 throwErrno loc  =
287   do
288     errno <- getErrno
289     ioError (errnoToIOError loc errno Nothing Nothing)
290
291
292 -- guards for IO operations that may fail
293 -- --------------------------------------
294
295 -- guard an IO operation and throw an "errno" based exception of the result
296 -- value of the IO operation meets the given predicate
297 --
298 throwErrnoIf            :: (a -> Bool) -> String -> IO a -> IO a
299 throwErrnoIf pred loc f  = 
300   do
301     res <- f
302     if pred res then throwErrno loc else return res
303
304 -- as `throwErrnoIf', but discards the result
305 --
306 throwErrnoIf_            :: (a -> Bool) -> String -> IO a -> IO ()
307 throwErrnoIf_ pred loc f  = void $ throwErrnoIf pred loc f
308
309 -- as `throwErrnoIf', but retries interrupted IO operations (ie, those whose
310 -- flag `EINTR')
311 --
312 throwErrnoIfRetry            :: (a -> Bool) -> String -> IO a -> IO a
313 throwErrnoIfRetry pred loc f  = 
314   do
315     res <- f
316     if pred res
317       then do
318         err <- getErrno
319         if err == eINTR
320           then throwErrnoIfRetry pred loc f
321           else throwErrno loc
322       else return res
323
324 -- as `throwErrnoIfRetry', but checks for operations that would block and
325 -- executes an alternative action in that case.
326
327 throwErrnoIfRetryMayBlock  :: (a -> Bool) -> String -> IO a -> IO b -> IO a
328 throwErrnoIfRetryMayBlock pred loc f on_block  = 
329   do
330     res <- f
331     if pred res
332       then do
333         err <- getErrno
334         if err == eINTR
335           then throwErrnoIfRetryMayBlock pred loc f on_block
336           else if err == eWOULDBLOCK || err == eAGAIN
337                  then do on_block; throwErrnoIfRetryMayBlock pred loc f on_block
338                  else throwErrno loc
339       else return res
340
341 -- as `throwErrnoIfRetry', but discards the result
342 --
343 throwErrnoIfRetry_            :: (a -> Bool) -> String -> IO a -> IO ()
344 throwErrnoIfRetry_ pred loc f  = void $ throwErrnoIfRetry pred loc f
345
346 -- as `throwErrnoIfRetryMayBlock', but discards the result
347 --
348 throwErrnoIfRetryMayBlock_ :: (a -> Bool) -> String -> IO a -> IO b -> IO ()
349 throwErrnoIfRetryMayBlock_ pred loc f on_block 
350   = void $ throwErrnoIfRetryMayBlock pred loc f on_block
351
352 -- throws "errno" if a result of "-1" is returned
353 --
354 throwErrnoIfMinus1 :: Num a => String -> IO a -> IO a
355 throwErrnoIfMinus1  = throwErrnoIf (== -1)
356
357 -- as `throwErrnoIfMinus1', but discards the result
358 --
359 throwErrnoIfMinus1_ :: Num a => String -> IO a -> IO ()
360 throwErrnoIfMinus1_  = throwErrnoIf_ (== -1)
361
362 -- throws "errno" if a result of "-1" is returned, but retries in case of an
363 -- interrupted operation
364 --
365 throwErrnoIfMinus1Retry :: Num a => String -> IO a -> IO a
366 throwErrnoIfMinus1Retry  = throwErrnoIfRetry (== -1)
367
368 -- as `throwErrnoIfMinus1', but discards the result
369 --
370 throwErrnoIfMinus1Retry_ :: Num a => String -> IO a -> IO ()
371 throwErrnoIfMinus1Retry_  = throwErrnoIfRetry_ (== -1)
372
373 -- as throwErrnoIfMinus1Retry, but checks for operations that would block
374 --
375 throwErrnoIfMinus1RetryMayBlock :: Num a => String -> IO a -> IO b -> IO a
376 throwErrnoIfMinus1RetryMayBlock  = throwErrnoIfRetryMayBlock (== -1)
377
378 -- as `throwErrnoIfMinus1RetryMayBlock', but discards the result
379 --
380 throwErrnoIfMinus1RetryMayBlock_ :: Num a => String -> IO a -> IO b -> IO ()
381 throwErrnoIfMinus1RetryMayBlock_  = throwErrnoIfRetryMayBlock_ (== -1)
382
383 -- throws "errno" if a result of a NULL pointer is returned
384 --
385 throwErrnoIfNull :: String -> IO (Ptr a) -> IO (Ptr a)
386 throwErrnoIfNull  = throwErrnoIf (== nullPtr)
387
388 -- throws "errno" if a result of a NULL pointer is returned, but retries in
389 -- case of an interrupted operation
390 --
391 throwErrnoIfNullRetry :: String -> IO (Ptr a) -> IO (Ptr a)
392 throwErrnoIfNullRetry  = throwErrnoIfRetry (== nullPtr)
393
394 -- as throwErrnoIfNullRetry, but checks for operations that would block
395 --
396 throwErrnoIfNullRetryMayBlock :: String -> IO (Ptr a) -> IO b -> IO (Ptr a)
397 throwErrnoIfNullRetryMayBlock  = throwErrnoIfRetryMayBlock (== nullPtr)
398
399 -- conversion of an "errno" value into IO error
400 -- --------------------------------------------
401
402 -- convert a location string, an "errno" value, an optional handle,
403 -- and an optional filename into a matching IO error
404 --
405 errnoToIOError :: String -> Errno -> Maybe Handle -> Maybe String -> IOError
406 errnoToIOError loc errno maybeHdl maybeName = unsafePerformIO $ do
407     str <- strerror errno >>= peekCString
408 #if __GLASGOW_HASKELL__
409     return (IOException (IOError maybeHdl errType loc str maybeName))
410     where
411     errType
412         | errno == eOK             = OtherError
413         | errno == e2BIG           = ResourceExhausted
414         | errno == eACCES          = PermissionDenied
415         | errno == eADDRINUSE      = ResourceBusy
416         | errno == eADDRNOTAVAIL   = UnsupportedOperation
417         | errno == eADV            = OtherError
418         | errno == eAFNOSUPPORT    = UnsupportedOperation
419         | errno == eAGAIN          = ResourceExhausted
420         | errno == eALREADY        = AlreadyExists
421         | errno == eBADF           = OtherError
422         | errno == eBADMSG         = InappropriateType
423         | errno == eBADRPC         = OtherError
424         | errno == eBUSY           = ResourceBusy
425         | errno == eCHILD          = NoSuchThing
426         | errno == eCOMM           = ResourceVanished
427         | errno == eCONNABORTED    = OtherError
428         | errno == eCONNREFUSED    = NoSuchThing
429         | errno == eCONNRESET      = ResourceVanished
430         | errno == eDEADLK         = ResourceBusy
431         | errno == eDESTADDRREQ    = InvalidArgument
432         | errno == eDIRTY          = UnsatisfiedConstraints
433         | errno == eDOM            = InvalidArgument
434         | errno == eDQUOT          = PermissionDenied
435         | errno == eEXIST          = AlreadyExists
436         | errno == eFAULT          = OtherError
437         | errno == eFBIG           = PermissionDenied
438         | errno == eFTYPE          = InappropriateType
439         | errno == eHOSTDOWN       = NoSuchThing
440         | errno == eHOSTUNREACH    = NoSuchThing
441         | errno == eIDRM           = ResourceVanished
442         | errno == eILSEQ          = InvalidArgument
443         | errno == eINPROGRESS     = AlreadyExists
444         | errno == eINTR           = Interrupted
445         | errno == eINVAL          = InvalidArgument
446         | errno == eIO             = HardwareFault
447         | errno == eISCONN         = AlreadyExists
448         | errno == eISDIR          = InappropriateType
449         | errno == eLOOP           = InvalidArgument
450         | errno == eMFILE          = ResourceExhausted
451         | errno == eMLINK          = ResourceExhausted
452         | errno == eMSGSIZE        = ResourceExhausted
453         | errno == eMULTIHOP       = UnsupportedOperation
454         | errno == eNAMETOOLONG    = InvalidArgument
455         | errno == eNETDOWN        = ResourceVanished
456         | errno == eNETRESET       = ResourceVanished
457         | errno == eNETUNREACH     = NoSuchThing
458         | errno == eNFILE          = ResourceExhausted
459         | errno == eNOBUFS         = ResourceExhausted
460         | errno == eNODATA         = NoSuchThing
461         | errno == eNODEV          = UnsupportedOperation
462         | errno == eNOENT          = NoSuchThing
463         | errno == eNOEXEC         = InvalidArgument
464         | errno == eNOLCK          = ResourceExhausted
465         | errno == eNOLINK         = ResourceVanished
466         | errno == eNOMEM          = ResourceExhausted
467         | errno == eNOMSG          = NoSuchThing
468         | errno == eNONET          = NoSuchThing
469         | errno == eNOPROTOOPT     = UnsupportedOperation
470         | errno == eNOSPC          = ResourceExhausted
471         | errno == eNOSR           = ResourceExhausted
472         | errno == eNOSTR          = InvalidArgument
473         | errno == eNOSYS          = UnsupportedOperation
474         | errno == eNOTBLK         = InvalidArgument
475         | errno == eNOTCONN        = InvalidArgument
476         | errno == eNOTDIR         = InappropriateType
477         | errno == eNOTEMPTY       = UnsatisfiedConstraints
478         | errno == eNOTSOCK        = InvalidArgument
479         | errno == eNOTTY          = IllegalOperation
480         | errno == eNXIO           = NoSuchThing
481         | errno == eOPNOTSUPP      = UnsupportedOperation
482         | errno == ePERM           = PermissionDenied
483         | errno == ePFNOSUPPORT    = UnsupportedOperation
484         | errno == ePIPE           = ResourceVanished
485         | errno == ePROCLIM        = PermissionDenied
486         | errno == ePROCUNAVAIL    = UnsupportedOperation
487         | errno == ePROGMISMATCH   = ProtocolError
488         | errno == ePROGUNAVAIL    = UnsupportedOperation
489         | errno == ePROTO          = ProtocolError
490         | errno == ePROTONOSUPPORT = ProtocolError
491         | errno == ePROTOTYPE      = ProtocolError
492         | errno == eRANGE          = UnsupportedOperation
493         | errno == eREMCHG         = ResourceVanished
494         | errno == eREMOTE         = IllegalOperation
495         | errno == eROFS           = PermissionDenied
496         | errno == eRPCMISMATCH    = ProtocolError
497         | errno == eRREMOTE        = IllegalOperation
498         | errno == eSHUTDOWN       = IllegalOperation
499         | errno == eSOCKTNOSUPPORT = UnsupportedOperation
500         | errno == eSPIPE          = UnsupportedOperation
501         | errno == eSRCH           = NoSuchThing
502         | errno == eSRMNT          = UnsatisfiedConstraints
503         | errno == eSTALE          = ResourceVanished
504         | errno == eTIME           = TimeExpired
505         | errno == eTIMEDOUT       = TimeExpired
506         | errno == eTOOMANYREFS    = ResourceExhausted
507         | errno == eTXTBSY         = ResourceBusy
508         | errno == eUSERS          = ResourceExhausted
509         | errno == eWOULDBLOCK     = OtherError
510         | errno == eXDEV           = UnsupportedOperation
511         | otherwise                = OtherError
512 #else
513     return (userError (loc ++ ": " ++ str ++ maybe "" (": "++) maybeName))
514 #endif
515
516 foreign import ccall unsafe strerror :: Errno -> IO (Ptr CChar)
517
518
519 -- Dreadfully tedious callouts to wrappers which define  the
520 -- actual values for the error codes.
521 foreign import ccall unsafe "prel_error_E2BIG" cCONST_E2BIG :: CInt
522 foreign import ccall unsafe "prel_error_EACCES" cCONST_EACCES :: CInt
523 foreign import ccall unsafe "prel_error_EADDRINUSE" cCONST_EADDRINUSE :: CInt
524 foreign import ccall unsafe "prel_error_EADDRNOTAVAIL" cCONST_EADDRNOTAVAIL :: CInt
525 foreign import ccall unsafe "prel_error_EADV" cCONST_EADV :: CInt
526 foreign import ccall unsafe "prel_error_EAFNOSUPPORT" cCONST_EAFNOSUPPORT :: CInt
527 foreign import ccall unsafe "prel_error_EAGAIN" cCONST_EAGAIN :: CInt
528 foreign import ccall unsafe "prel_error_EALREADY" cCONST_EALREADY :: CInt
529 foreign import ccall unsafe "prel_error_EBADF" cCONST_EBADF :: CInt
530 foreign import ccall unsafe "prel_error_EBADMSG" cCONST_EBADMSG :: CInt
531 foreign import ccall unsafe "prel_error_EBADRPC" cCONST_EBADRPC :: CInt
532 foreign import ccall unsafe "prel_error_EBUSY" cCONST_EBUSY :: CInt
533 foreign import ccall unsafe "prel_error_ECHILD" cCONST_ECHILD :: CInt
534 foreign import ccall unsafe "prel_error_ECOMM" cCONST_ECOMM :: CInt
535 foreign import ccall unsafe "prel_error_ECONNABORTED" cCONST_ECONNABORTED :: CInt
536 foreign import ccall unsafe "prel_error_ECONNREFUSED" cCONST_ECONNREFUSED :: CInt
537 foreign import ccall unsafe "prel_error_ECONNRESET" cCONST_ECONNRESET :: CInt
538 foreign import ccall unsafe "prel_error_EDEADLK" cCONST_EDEADLK :: CInt
539 foreign import ccall unsafe "prel_error_EDESTADDRREQ" cCONST_EDESTADDRREQ :: CInt
540 foreign import ccall unsafe "prel_error_EDIRTY" cCONST_EDIRTY :: CInt
541 foreign import ccall unsafe "prel_error_EDOM" cCONST_EDOM :: CInt
542 foreign import ccall unsafe "prel_error_EDQUOT" cCONST_EDQUOT :: CInt
543 foreign import ccall unsafe "prel_error_EEXIST" cCONST_EEXIST :: CInt
544 foreign import ccall unsafe "prel_error_EFAULT" cCONST_EFAULT :: CInt
545 foreign import ccall unsafe "prel_error_EFBIG" cCONST_EFBIG :: CInt
546 foreign import ccall unsafe "prel_error_EFTYPE" cCONST_EFTYPE :: CInt
547 foreign import ccall unsafe "prel_error_EHOSTDOWN" cCONST_EHOSTDOWN :: CInt
548 foreign import ccall unsafe "prel_error_EHOSTUNREACH" cCONST_EHOSTUNREACH :: CInt
549 foreign import ccall unsafe "prel_error_EIDRM" cCONST_EIDRM :: CInt
550 foreign import ccall unsafe "prel_error_EILSEQ" cCONST_EILSEQ :: CInt
551 foreign import ccall unsafe "prel_error_EINPROGRESS" cCONST_EINPROGRESS :: CInt
552 foreign import ccall unsafe "prel_error_EINTR" cCONST_EINTR :: CInt
553 foreign import ccall unsafe "prel_error_EINVAL" cCONST_EINVAL :: CInt
554 foreign import ccall unsafe "prel_error_EIO" cCONST_EIO :: CInt
555 foreign import ccall unsafe "prel_error_EISCONN" cCONST_EISCONN :: CInt
556 foreign import ccall unsafe "prel_error_EISDIR" cCONST_EISDIR :: CInt
557 foreign import ccall unsafe "prel_error_ELOOP" cCONST_ELOOP :: CInt
558 foreign import ccall unsafe "prel_error_EMFILE" cCONST_EMFILE :: CInt
559 foreign import ccall unsafe "prel_error_EMLINK" cCONST_EMLINK :: CInt
560 foreign import ccall unsafe "prel_error_EMSGSIZE" cCONST_EMSGSIZE :: CInt
561 foreign import ccall unsafe "prel_error_EMULTIHOP" cCONST_EMULTIHOP :: CInt
562 foreign import ccall unsafe "prel_error_ENAMETOOLONG" cCONST_ENAMETOOLONG :: CInt
563 foreign import ccall unsafe "prel_error_ENETDOWN" cCONST_ENETDOWN :: CInt
564 foreign import ccall unsafe "prel_error_ENETRESET" cCONST_ENETRESET :: CInt
565 foreign import ccall unsafe "prel_error_ENETUNREACH" cCONST_ENETUNREACH :: CInt
566 foreign import ccall unsafe "prel_error_ENFILE" cCONST_ENFILE :: CInt
567 foreign import ccall unsafe "prel_error_ENOBUFS" cCONST_ENOBUFS :: CInt
568 foreign import ccall unsafe "prel_error_ENODATA" cCONST_ENODATA :: CInt
569 foreign import ccall unsafe "prel_error_ENODEV" cCONST_ENODEV :: CInt
570 foreign import ccall unsafe "prel_error_ENOENT" cCONST_ENOENT :: CInt
571 foreign import ccall unsafe "prel_error_ENOEXEC" cCONST_ENOEXEC :: CInt
572 foreign import ccall unsafe "prel_error_ENOLCK" cCONST_ENOLCK :: CInt
573 foreign import ccall unsafe "prel_error_ENOLINK" cCONST_ENOLINK :: CInt
574 foreign import ccall unsafe "prel_error_ENOMEM" cCONST_ENOMEM :: CInt
575 foreign import ccall unsafe "prel_error_ENOMSG" cCONST_ENOMSG :: CInt
576 foreign import ccall unsafe "prel_error_ENONET" cCONST_ENONET :: CInt
577 foreign import ccall unsafe "prel_error_ENOPROTOOPT" cCONST_ENOPROTOOPT :: CInt
578 foreign import ccall unsafe "prel_error_ENOSPC" cCONST_ENOSPC :: CInt
579 foreign import ccall unsafe "prel_error_ENOSR" cCONST_ENOSR :: CInt
580 foreign import ccall unsafe "prel_error_ENOSTR" cCONST_ENOSTR :: CInt
581 foreign import ccall unsafe "prel_error_ENOSYS" cCONST_ENOSYS :: CInt
582 foreign import ccall unsafe "prel_error_ENOTBLK" cCONST_ENOTBLK :: CInt
583 foreign import ccall unsafe "prel_error_ENOTCONN" cCONST_ENOTCONN :: CInt
584 foreign import ccall unsafe "prel_error_ENOTDIR" cCONST_ENOTDIR :: CInt
585 foreign import ccall unsafe "prel_error_ENOTEMPTY" cCONST_ENOTEMPTY :: CInt
586 foreign import ccall unsafe "prel_error_ENOTSOCK" cCONST_ENOTSOCK :: CInt
587 foreign import ccall unsafe "prel_error_ENOTTY" cCONST_ENOTTY :: CInt
588 foreign import ccall unsafe "prel_error_ENXIO" cCONST_ENXIO :: CInt
589 foreign import ccall unsafe "prel_error_EOPNOTSUPP" cCONST_EOPNOTSUPP :: CInt
590 foreign import ccall unsafe "prel_error_EPERM" cCONST_EPERM :: CInt
591 foreign import ccall unsafe "prel_error_EPFNOSUPPORT" cCONST_EPFNOSUPPORT :: CInt
592 foreign import ccall unsafe "prel_error_EPIPE" cCONST_EPIPE :: CInt
593 foreign import ccall unsafe "prel_error_EPROCLIM" cCONST_EPROCLIM :: CInt
594 foreign import ccall unsafe "prel_error_EPROCUNAVAIL" cCONST_EPROCUNAVAIL :: CInt
595 foreign import ccall unsafe "prel_error_EPROGMISMATCH" cCONST_EPROGMISMATCH :: CInt
596 foreign import ccall unsafe "prel_error_EPROGUNAVAIL" cCONST_EPROGUNAVAIL :: CInt
597 foreign import ccall unsafe "prel_error_EPROTO" cCONST_EPROTO :: CInt
598 foreign import ccall unsafe "prel_error_EPROTONOSUPPORT" cCONST_EPROTONOSUPPORT :: CInt
599 foreign import ccall unsafe "prel_error_EPROTOTYPE" cCONST_EPROTOTYPE :: CInt
600 foreign import ccall unsafe "prel_error_ERANGE" cCONST_ERANGE :: CInt
601 foreign import ccall unsafe "prel_error_EREMCHG" cCONST_EREMCHG :: CInt
602 foreign import ccall unsafe "prel_error_EREMOTE" cCONST_EREMOTE :: CInt
603 foreign import ccall unsafe "prel_error_EROFS" cCONST_EROFS :: CInt
604 foreign import ccall unsafe "prel_error_ERPCMISMATCH" cCONST_ERPCMISMATCH :: CInt
605 foreign import ccall unsafe "prel_error_ERREMOTE" cCONST_ERREMOTE :: CInt
606 foreign import ccall unsafe "prel_error_ESHUTDOWN" cCONST_ESHUTDOWN :: CInt
607 foreign import ccall unsafe "prel_error_ESOCKTNOSUPPORT" cCONST_ESOCKTNOSUPPORT :: CInt
608 foreign import ccall unsafe "prel_error_ESPIPE" cCONST_ESPIPE :: CInt
609 foreign import ccall unsafe "prel_error_ESRCH" cCONST_ESRCH :: CInt
610 foreign import ccall unsafe "prel_error_ESRMNT" cCONST_ESRMNT :: CInt
611 foreign import ccall unsafe "prel_error_ESTALE" cCONST_ESTALE :: CInt
612 foreign import ccall unsafe "prel_error_ETIME" cCONST_ETIME :: CInt
613 foreign import ccall unsafe "prel_error_ETIMEDOUT" cCONST_ETIMEDOUT :: CInt
614 foreign import ccall unsafe "prel_error_ETOOMANYREFS" cCONST_ETOOMANYREFS :: CInt
615 foreign import ccall unsafe "prel_error_ETXTBSY" cCONST_ETXTBSY :: CInt
616 foreign import ccall unsafe "prel_error_EUSERS" cCONST_EUSERS :: CInt
617 foreign import ccall unsafe "prel_error_EWOULDBLOCK" cCONST_EWOULDBLOCK :: CInt
618 foreign import ccall unsafe "prel_error_EXDEV" cCONST_EXDEV :: CInt
619