9c99ddf54570f7229b35760e36d31255a93873d0
[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/base/LICENSE)
7 -- 
8 -- Maintainer  :  ffi@haskell.org
9 -- Stability   :  provisional
10 -- Portability :  portable
11 --
12 -- C-specific Marshalling support: Handling of C \"errno\" error codes.
13 --
14 -----------------------------------------------------------------------------
15
16 module Foreign.C.Error (
17
18   -- * Haskell representations of @errno@ values
19
20   Errno(..),            -- instance: Eq
21
22   -- ** Common @errno@ symbols
23   -- | Different operating systems and\/or C libraries often support
24   -- different values of @errno@.  This module defines the common values,
25   -- but due to the open definition of 'Errno' users may add definitions
26   -- which are not predefined.
27   eOK, e2BIG, eACCES, eADDRINUSE, eADDRNOTAVAIL, eADV, eAFNOSUPPORT, eAGAIN, 
28   eALREADY, eBADF, eBADMSG, eBADRPC, eBUSY, eCHILD, eCOMM, eCONNABORTED, 
29   eCONNREFUSED, eCONNRESET, eDEADLK, eDESTADDRREQ, eDIRTY, eDOM, eDQUOT, 
30   eEXIST, eFAULT, eFBIG, eFTYPE, eHOSTDOWN, eHOSTUNREACH, eIDRM, eILSEQ, 
31   eINPROGRESS, eINTR, eINVAL, eIO, eISCONN, eISDIR, eLOOP, eMFILE, eMLINK, 
32   eMSGSIZE, eMULTIHOP, eNAMETOOLONG, eNETDOWN, eNETRESET, eNETUNREACH, 
33   eNFILE, eNOBUFS, eNODATA, eNODEV, eNOENT, eNOEXEC, eNOLCK, eNOLINK, 
34   eNOMEM, eNOMSG, eNONET, eNOPROTOOPT, eNOSPC, eNOSR, eNOSTR, eNOSYS, 
35   eNOTBLK, eNOTCONN, eNOTDIR, eNOTEMPTY, eNOTSOCK, eNOTTY, eNXIO, 
36   eOPNOTSUPP, ePERM, ePFNOSUPPORT, ePIPE, ePROCLIM, ePROCUNAVAIL, 
37   ePROGMISMATCH, ePROGUNAVAIL, ePROTO, ePROTONOSUPPORT, ePROTOTYPE, 
38   eRANGE, eREMCHG, eREMOTE, eROFS, eRPCMISMATCH, eRREMOTE, eSHUTDOWN, 
39   eSOCKTNOSUPPORT, eSPIPE, eSRCH, eSRMNT, eSTALE, eTIME, eTIMEDOUT, 
40   eTOOMANYREFS, eTXTBSY, eUSERS, eWOULDBLOCK, eXDEV,
41
42   -- ** 'Errno' functions
43                         -- :: Errno
44   isValidErrno,         -- :: Errno -> Bool
45
46   -- access to the current thread's "errno" value
47   --
48   getErrno,             -- :: IO Errno
49   resetErrno,           -- :: IO ()
50
51   -- conversion of an "errno" value into IO error
52   --
53   errnoToIOError,       -- :: String       -- location
54                         -- -> Errno        -- errno
55                         -- -> Maybe Handle -- handle
56                         -- -> Maybe String -- filename
57                         -- -> IOError
58
59   -- throw current "errno" value
60   --
61   throwErrno,           -- ::                String               -> IO a
62
63   -- ** Guards for IO operations that may fail
64
65   throwErrnoIf,         -- :: (a -> Bool) -> String -> IO a       -> IO a
66   throwErrnoIf_,        -- :: (a -> Bool) -> String -> IO a       -> IO ()
67   throwErrnoIfRetry,    -- :: (a -> Bool) -> String -> IO a       -> IO a
68   throwErrnoIfRetry_,   -- :: (a -> Bool) -> String -> IO a       -> IO ()
69   throwErrnoIfMinus1,   -- :: Num a 
70                         -- =>                String -> IO a       -> IO a
71   throwErrnoIfMinus1_,  -- :: Num a 
72                         -- =>                String -> IO a       -> IO ()
73   throwErrnoIfMinus1Retry,  
74                         -- :: Num a 
75                         -- =>                String -> IO a       -> IO a
76   throwErrnoIfMinus1Retry_,  
77                         -- :: Num a 
78                         -- =>                String -> IO a       -> IO ()
79   throwErrnoIfNull,     -- ::                String -> IO (Ptr a) -> IO (Ptr a)
80   throwErrnoIfNullRetry,-- ::                String -> IO (Ptr a) -> IO (Ptr a)
81
82   throwErrnoIfRetryMayBlock, 
83   throwErrnoIfRetryMayBlock_,
84   throwErrnoIfMinus1RetryMayBlock,
85   throwErrnoIfMinus1RetryMayBlock_,  
86   throwErrnoIfNullRetryMayBlock
87 ) where
88
89
90 -- this is were we get the CONST_XXX definitions from that configure
91 -- calculated for us
92 --
93 #ifndef __NHC__
94 #include "HsBaseConfig.h"
95 #endif
96
97 -- system dependent imports
98 -- ------------------------
99
100 -- GHC allows us to get at the guts inside IO errors/exceptions
101 --
102 #if __GLASGOW_HASKELL__
103 import GHC.IOBase (IOException(..), IOErrorType(..))
104 #endif /* __GLASGOW_HASKELL__ */
105
106
107 -- regular imports
108 -- ---------------
109
110 import Foreign.Storable
111 import Foreign.Ptr
112 import Foreign.C.Types
113 import Foreign.C.String
114 import Foreign.Marshal.Error    ( void )
115 import Data.Maybe
116
117 #if __GLASGOW_HASKELL__
118 import GHC.IOBase
119 import GHC.Num
120 import GHC.Base
121 #else
122 import System.IO                ( Handle )
123 import System.IO.Error          ( IOError, ioError )
124 import System.IO.Unsafe         ( unsafePerformIO )
125 #endif
126
127 #ifdef __HUGS__
128 {-# CFILES cbits/PrelIOUtils.c #-}
129 #endif
130
131
132 -- "errno" type
133 -- ------------
134
135 -- | Haskell representation for @errno@ values.
136 -- The implementation is deliberately exposed, to allow users to add
137 -- their own definitions of 'Errno' values.
138
139 newtype Errno = Errno CInt
140
141 instance Eq Errno where
142   errno1@(Errno no1) == errno2@(Errno no2) 
143     | isValidErrno errno1 && isValidErrno errno2 = no1 == no2
144     | otherwise                                  = False
145
146 -- common "errno" symbols
147 --
148 eOK, e2BIG, eACCES, eADDRINUSE, eADDRNOTAVAIL, eADV, eAFNOSUPPORT, eAGAIN, 
149   eALREADY, eBADF, eBADMSG, eBADRPC, eBUSY, eCHILD, eCOMM, eCONNABORTED, 
150   eCONNREFUSED, eCONNRESET, eDEADLK, eDESTADDRREQ, eDIRTY, eDOM, eDQUOT, 
151   eEXIST, eFAULT, eFBIG, eFTYPE, eHOSTDOWN, eHOSTUNREACH, eIDRM, eILSEQ, 
152   eINPROGRESS, eINTR, eINVAL, eIO, eISCONN, eISDIR, eLOOP, eMFILE, eMLINK, 
153   eMSGSIZE, eMULTIHOP, eNAMETOOLONG, eNETDOWN, eNETRESET, eNETUNREACH, 
154   eNFILE, eNOBUFS, eNODATA, eNODEV, eNOENT, eNOEXEC, eNOLCK, eNOLINK, 
155   eNOMEM, eNOMSG, eNONET, eNOPROTOOPT, eNOSPC, eNOSR, eNOSTR, eNOSYS, 
156   eNOTBLK, eNOTCONN, eNOTDIR, eNOTEMPTY, eNOTSOCK, eNOTTY, eNXIO, 
157   eOPNOTSUPP, ePERM, ePFNOSUPPORT, ePIPE, ePROCLIM, ePROCUNAVAIL, 
158   ePROGMISMATCH, ePROGUNAVAIL, ePROTO, ePROTONOSUPPORT, ePROTOTYPE, 
159   eRANGE, eREMCHG, eREMOTE, eROFS, eRPCMISMATCH, eRREMOTE, eSHUTDOWN, 
160   eSOCKTNOSUPPORT, eSPIPE, eSRCH, eSRMNT, eSTALE, eTIME, eTIMEDOUT, 
161   eTOOMANYREFS, eTXTBSY, eUSERS, eWOULDBLOCK, eXDEV                    :: Errno
162 --
163 -- the cCONST_XXX identifiers are cpp symbols whose value is computed by
164 -- configure 
165 --
166 eOK             = Errno 0
167 #ifdef __NHC__
168 #include "Errno.hs"
169 #else
170 e2BIG           = Errno (CONST_E2BIG)
171 eACCES          = Errno (CONST_EACCES)
172 eADDRINUSE      = Errno (CONST_EADDRINUSE)
173 eADDRNOTAVAIL   = Errno (CONST_EADDRNOTAVAIL)
174 eADV            = Errno (CONST_EADV)
175 eAFNOSUPPORT    = Errno (CONST_EAFNOSUPPORT)
176 eAGAIN          = Errno (CONST_EAGAIN)
177 eALREADY        = Errno (CONST_EALREADY)
178 eBADF           = Errno (CONST_EBADF)
179 eBADMSG         = Errno (CONST_EBADMSG)
180 eBADRPC         = Errno (CONST_EBADRPC)
181 eBUSY           = Errno (CONST_EBUSY)
182 eCHILD          = Errno (CONST_ECHILD)
183 eCOMM           = Errno (CONST_ECOMM)
184 eCONNABORTED    = Errno (CONST_ECONNABORTED)
185 eCONNREFUSED    = Errno (CONST_ECONNREFUSED)
186 eCONNRESET      = Errno (CONST_ECONNRESET)
187 eDEADLK         = Errno (CONST_EDEADLK)
188 eDESTADDRREQ    = Errno (CONST_EDESTADDRREQ)
189 eDIRTY          = Errno (CONST_EDIRTY)
190 eDOM            = Errno (CONST_EDOM)
191 eDQUOT          = Errno (CONST_EDQUOT)
192 eEXIST          = Errno (CONST_EEXIST)
193 eFAULT          = Errno (CONST_EFAULT)
194 eFBIG           = Errno (CONST_EFBIG)
195 eFTYPE          = Errno (CONST_EFTYPE)
196 eHOSTDOWN       = Errno (CONST_EHOSTDOWN)
197 eHOSTUNREACH    = Errno (CONST_EHOSTUNREACH)
198 eIDRM           = Errno (CONST_EIDRM)
199 eILSEQ          = Errno (CONST_EILSEQ)
200 eINPROGRESS     = Errno (CONST_EINPROGRESS)
201 eINTR           = Errno (CONST_EINTR)
202 eINVAL          = Errno (CONST_EINVAL)
203 eIO             = Errno (CONST_EIO)
204 eISCONN         = Errno (CONST_EISCONN)
205 eISDIR          = Errno (CONST_EISDIR)
206 eLOOP           = Errno (CONST_ELOOP)
207 eMFILE          = Errno (CONST_EMFILE)
208 eMLINK          = Errno (CONST_EMLINK)
209 eMSGSIZE        = Errno (CONST_EMSGSIZE)
210 eMULTIHOP       = Errno (CONST_EMULTIHOP)
211 eNAMETOOLONG    = Errno (CONST_ENAMETOOLONG)
212 eNETDOWN        = Errno (CONST_ENETDOWN)
213 eNETRESET       = Errno (CONST_ENETRESET)
214 eNETUNREACH     = Errno (CONST_ENETUNREACH)
215 eNFILE          = Errno (CONST_ENFILE)
216 eNOBUFS         = Errno (CONST_ENOBUFS)
217 eNODATA         = Errno (CONST_ENODATA)
218 eNODEV          = Errno (CONST_ENODEV)
219 eNOENT          = Errno (CONST_ENOENT)
220 eNOEXEC         = Errno (CONST_ENOEXEC)
221 eNOLCK          = Errno (CONST_ENOLCK)
222 eNOLINK         = Errno (CONST_ENOLINK)
223 eNOMEM          = Errno (CONST_ENOMEM)
224 eNOMSG          = Errno (CONST_ENOMSG)
225 eNONET          = Errno (CONST_ENONET)
226 eNOPROTOOPT     = Errno (CONST_ENOPROTOOPT)
227 eNOSPC          = Errno (CONST_ENOSPC)
228 eNOSR           = Errno (CONST_ENOSR)
229 eNOSTR          = Errno (CONST_ENOSTR)
230 eNOSYS          = Errno (CONST_ENOSYS)
231 eNOTBLK         = Errno (CONST_ENOTBLK)
232 eNOTCONN        = Errno (CONST_ENOTCONN)
233 eNOTDIR         = Errno (CONST_ENOTDIR)
234 eNOTEMPTY       = Errno (CONST_ENOTEMPTY)
235 eNOTSOCK        = Errno (CONST_ENOTSOCK)
236 eNOTTY          = Errno (CONST_ENOTTY)
237 eNXIO           = Errno (CONST_ENXIO)
238 eOPNOTSUPP      = Errno (CONST_EOPNOTSUPP)
239 ePERM           = Errno (CONST_EPERM)
240 ePFNOSUPPORT    = Errno (CONST_EPFNOSUPPORT)
241 ePIPE           = Errno (CONST_EPIPE)
242 ePROCLIM        = Errno (CONST_EPROCLIM)
243 ePROCUNAVAIL    = Errno (CONST_EPROCUNAVAIL)
244 ePROGMISMATCH   = Errno (CONST_EPROGMISMATCH)
245 ePROGUNAVAIL    = Errno (CONST_EPROGUNAVAIL)
246 ePROTO          = Errno (CONST_EPROTO)
247 ePROTONOSUPPORT = Errno (CONST_EPROTONOSUPPORT)
248 ePROTOTYPE      = Errno (CONST_EPROTOTYPE)
249 eRANGE          = Errno (CONST_ERANGE)
250 eREMCHG         = Errno (CONST_EREMCHG)
251 eREMOTE         = Errno (CONST_EREMOTE)
252 eROFS           = Errno (CONST_EROFS)
253 eRPCMISMATCH    = Errno (CONST_ERPCMISMATCH)
254 eRREMOTE        = Errno (CONST_ERREMOTE)
255 eSHUTDOWN       = Errno (CONST_ESHUTDOWN)
256 eSOCKTNOSUPPORT = Errno (CONST_ESOCKTNOSUPPORT)
257 eSPIPE          = Errno (CONST_ESPIPE)
258 eSRCH           = Errno (CONST_ESRCH)
259 eSRMNT          = Errno (CONST_ESRMNT)
260 eSTALE          = Errno (CONST_ESTALE)
261 eTIME           = Errno (CONST_ETIME)
262 eTIMEDOUT       = Errno (CONST_ETIMEDOUT)
263 eTOOMANYREFS    = Errno (CONST_ETOOMANYREFS)
264 eTXTBSY         = Errno (CONST_ETXTBSY)
265 eUSERS          = Errno (CONST_EUSERS)
266 eWOULDBLOCK     = Errno (CONST_EWOULDBLOCK)
267 eXDEV           = Errno (CONST_EXDEV)
268 #endif
269
270 -- | Yield 'True' if the given 'Errno' value is valid on the system.
271 -- This implies that the 'Eq' instance of 'Errno' is also system dependent
272 -- as it is only defined for valid values of 'Errno'.
273 --
274 isValidErrno               :: Errno -> Bool
275 --
276 -- the configure script sets all invalid "errno"s to -1
277 --
278 isValidErrno (Errno errno)  = errno /= -1
279
280
281 -- access to the current thread's "errno" value
282 -- --------------------------------------------
283
284 -- | Get the current value of @errno@ in the current thread.
285 --
286 getErrno :: IO Errno
287
288 -- We must call a C function to get the value of errno in general.  On
289 -- threaded systems, errno is hidden behind a C macro so that each OS
290 -- thread gets its own copy.
291 #ifdef __NHC__
292 getErrno = do e <- peek _errno; return (Errno e)
293 foreign import ccall unsafe "errno.h &errno" _errno :: Ptr CInt
294 #else
295 getErrno = do e <- get_errno; return (Errno e)
296 foreign import ccall unsafe "HsBase.h __hscore_get_errno" get_errno :: IO CInt
297 #endif
298
299 -- | Reset the current thread\'s @errno@ value to 'eOK'.
300 --
301 resetErrno :: IO ()
302
303 -- Again, setting errno has to be done via a C function.
304 #ifdef __NHC__
305 resetErrno = poke _errno 0
306 #else
307 resetErrno = set_errno 0
308 foreign import ccall unsafe "HsBase.h __hscore_set_errno" set_errno :: CInt -> IO ()
309 #endif
310
311 -- throw current "errno" value
312 -- ---------------------------
313
314 -- | Throw an 'IOError' corresponding to the current value of 'getErrno'.
315 --
316 throwErrno     :: String        -- ^ textual description of the error location
317                -> IO a
318 throwErrno loc  =
319   do
320     errno <- getErrno
321     ioError (errnoToIOError loc errno Nothing Nothing)
322
323
324 -- guards for IO operations that may fail
325 -- --------------------------------------
326
327 -- | Throw an 'IOError' corresponding to the current value of 'getErrno'
328 -- if the result value of the 'IO' action meets the given predicate.
329 --
330 throwErrnoIf    :: (a -> Bool)  -- ^ predicate to apply to the result value
331                                 -- of the 'IO' operation
332                 -> String       -- ^ textual description of the location
333                 -> IO a         -- ^ the 'IO' operation to be executed
334                 -> IO a
335 throwErrnoIf pred loc f  = 
336   do
337     res <- f
338     if pred res then throwErrno loc else return res
339
340 -- | as 'throwErrnoIf', but discards the result of the 'IO' action after
341 -- error handling.
342 --
343 throwErrnoIf_   :: (a -> Bool) -> String -> IO a -> IO ()
344 throwErrnoIf_ pred loc f  = void $ throwErrnoIf pred loc f
345
346 -- | as 'throwErrnoIf', but retry the 'IO' action when it yields the
347 -- error code 'eINTR' - this amounts to the standard retry loop for
348 -- interrupted POSIX system calls.
349 --
350 throwErrnoIfRetry            :: (a -> Bool) -> String -> IO a -> IO a
351 throwErrnoIfRetry pred loc f  = 
352   do
353     res <- f
354     if pred res
355       then do
356         err <- getErrno
357         if err == eINTR
358           then throwErrnoIfRetry pred loc f
359           else throwErrno loc
360       else return res
361
362 -- | as 'throwErrnoIfRetry', but checks for operations that would block and
363 -- executes an alternative action before retrying in that case.
364 --
365 throwErrnoIfRetryMayBlock
366                 :: (a -> Bool)  -- ^ predicate to apply to the result value
367                                 -- of the 'IO' operation
368                 -> String       -- ^ textual description of the location
369                 -> IO a         -- ^ the 'IO' operation to be executed
370                 -> IO b         -- ^ action to execute before retrying if
371                                 -- an immediate retry would block
372                 -> IO a
373 throwErrnoIfRetryMayBlock pred loc f on_block  = 
374   do
375     res <- f
376     if pred res
377       then do
378         err <- getErrno
379         if err == eINTR
380           then throwErrnoIfRetryMayBlock pred loc f on_block
381           else if err == eWOULDBLOCK || err == eAGAIN
382                  then do on_block; throwErrnoIfRetryMayBlock pred loc f on_block
383                  else throwErrno loc
384       else return res
385
386 -- | as 'throwErrnoIfRetry', but discards the result.
387 --
388 throwErrnoIfRetry_            :: (a -> Bool) -> String -> IO a -> IO ()
389 throwErrnoIfRetry_ pred loc f  = void $ throwErrnoIfRetry pred loc f
390
391 -- | as 'throwErrnoIfRetryMayBlock', but discards the result.
392 --
393 throwErrnoIfRetryMayBlock_ :: (a -> Bool) -> String -> IO a -> IO b -> IO ()
394 throwErrnoIfRetryMayBlock_ pred loc f on_block 
395   = void $ throwErrnoIfRetryMayBlock pred loc f on_block
396
397 -- | Throw an 'IOError' corresponding to the current value of 'getErrno'
398 -- if the 'IO' action returns a result of @-1@.
399 --
400 throwErrnoIfMinus1 :: Num a => String -> IO a -> IO a
401 throwErrnoIfMinus1  = throwErrnoIf (== -1)
402
403 -- | as 'throwErrnoIfMinus1', but discards the result.
404 --
405 throwErrnoIfMinus1_ :: Num a => String -> IO a -> IO ()
406 throwErrnoIfMinus1_  = throwErrnoIf_ (== -1)
407
408 -- | Throw an 'IOError' corresponding to the current value of 'getErrno'
409 -- if the 'IO' action returns a result of @-1@, but retries in case of
410 -- an interrupted operation.
411 --
412 throwErrnoIfMinus1Retry :: Num a => String -> IO a -> IO a
413 throwErrnoIfMinus1Retry  = throwErrnoIfRetry (== -1)
414
415 -- | as 'throwErrnoIfMinus1', but discards the result.
416 --
417 throwErrnoIfMinus1Retry_ :: Num a => String -> IO a -> IO ()
418 throwErrnoIfMinus1Retry_  = throwErrnoIfRetry_ (== -1)
419
420 -- | as 'throwErrnoIfMinus1Retry', but checks for operations that would block.
421 --
422 throwErrnoIfMinus1RetryMayBlock :: Num a => String -> IO a -> IO b -> IO a
423 throwErrnoIfMinus1RetryMayBlock  = throwErrnoIfRetryMayBlock (== -1)
424
425 -- | as 'throwErrnoIfMinus1RetryMayBlock', but discards the result.
426 --
427 throwErrnoIfMinus1RetryMayBlock_ :: Num a => String -> IO a -> IO b -> IO ()
428 throwErrnoIfMinus1RetryMayBlock_  = throwErrnoIfRetryMayBlock_ (== -1)
429
430 -- | Throw an 'IOError' corresponding to the current value of 'getErrno'
431 -- if the 'IO' action returns 'nullPtr'.
432 --
433 throwErrnoIfNull :: String -> IO (Ptr a) -> IO (Ptr a)
434 throwErrnoIfNull  = throwErrnoIf (== nullPtr)
435
436 -- | Throw an 'IOError' corresponding to the current value of 'getErrno'
437 -- if the 'IO' action returns 'nullPtr',
438 -- but retry in case of an interrupted operation.
439 --
440 throwErrnoIfNullRetry :: String -> IO (Ptr a) -> IO (Ptr a)
441 throwErrnoIfNullRetry  = throwErrnoIfRetry (== nullPtr)
442
443 -- | as 'throwErrnoIfNullRetry', but checks for operations that would block.
444 --
445 throwErrnoIfNullRetryMayBlock :: String -> IO (Ptr a) -> IO b -> IO (Ptr a)
446 throwErrnoIfNullRetryMayBlock  = throwErrnoIfRetryMayBlock (== nullPtr)
447
448 -- conversion of an "errno" value into IO error
449 -- --------------------------------------------
450
451 -- | Construct a Haskell 98 I\/O error based on the given 'Errno' value.
452 -- The optional information can be used to improve the accuracy of
453 -- error messages.
454 --
455 errnoToIOError  :: String       -- ^ the location where the error occurred
456                 -> Errno        -- ^ the error number
457                 -> Maybe Handle -- ^ optional handle associated with the error
458                 -> Maybe String -- ^ optional filename associated with the error
459                 -> IOError
460 errnoToIOError loc errno maybeHdl maybeName = unsafePerformIO $ do
461     str <- strerror errno >>= peekCString
462 #if __GLASGOW_HASKELL__
463     return (IOError maybeHdl errType loc str maybeName)
464     where
465     errType
466         | errno == eOK             = OtherError
467         | errno == e2BIG           = ResourceExhausted
468         | errno == eACCES          = PermissionDenied
469         | errno == eADDRINUSE      = ResourceBusy
470         | errno == eADDRNOTAVAIL   = UnsupportedOperation
471         | errno == eADV            = OtherError
472         | errno == eAFNOSUPPORT    = UnsupportedOperation
473         | errno == eAGAIN          = ResourceExhausted
474         | errno == eALREADY        = AlreadyExists
475         | errno == eBADF           = OtherError
476         | errno == eBADMSG         = InappropriateType
477         | errno == eBADRPC         = OtherError
478         | errno == eBUSY           = ResourceBusy
479         | errno == eCHILD          = NoSuchThing
480         | errno == eCOMM           = ResourceVanished
481         | errno == eCONNABORTED    = OtherError
482         | errno == eCONNREFUSED    = NoSuchThing
483         | errno == eCONNRESET      = ResourceVanished
484         | errno == eDEADLK         = ResourceBusy
485         | errno == eDESTADDRREQ    = InvalidArgument
486         | errno == eDIRTY          = UnsatisfiedConstraints
487         | errno == eDOM            = InvalidArgument
488         | errno == eDQUOT          = PermissionDenied
489         | errno == eEXIST          = AlreadyExists
490         | errno == eFAULT          = OtherError
491         | errno == eFBIG           = PermissionDenied
492         | errno == eFTYPE          = InappropriateType
493         | errno == eHOSTDOWN       = NoSuchThing
494         | errno == eHOSTUNREACH    = NoSuchThing
495         | errno == eIDRM           = ResourceVanished
496         | errno == eILSEQ          = InvalidArgument
497         | errno == eINPROGRESS     = AlreadyExists
498         | errno == eINTR           = Interrupted
499         | errno == eINVAL          = InvalidArgument
500         | errno == eIO             = HardwareFault
501         | errno == eISCONN         = AlreadyExists
502         | errno == eISDIR          = InappropriateType
503         | errno == eLOOP           = InvalidArgument
504         | errno == eMFILE          = ResourceExhausted
505         | errno == eMLINK          = ResourceExhausted
506         | errno == eMSGSIZE        = ResourceExhausted
507         | errno == eMULTIHOP       = UnsupportedOperation
508         | errno == eNAMETOOLONG    = InvalidArgument
509         | errno == eNETDOWN        = ResourceVanished
510         | errno == eNETRESET       = ResourceVanished
511         | errno == eNETUNREACH     = NoSuchThing
512         | errno == eNFILE          = ResourceExhausted
513         | errno == eNOBUFS         = ResourceExhausted
514         | errno == eNODATA         = NoSuchThing
515         | errno == eNODEV          = UnsupportedOperation
516         | errno == eNOENT          = NoSuchThing
517         | errno == eNOEXEC         = InvalidArgument
518         | errno == eNOLCK          = ResourceExhausted
519         | errno == eNOLINK         = ResourceVanished
520         | errno == eNOMEM          = ResourceExhausted
521         | errno == eNOMSG          = NoSuchThing
522         | errno == eNONET          = NoSuchThing
523         | errno == eNOPROTOOPT     = UnsupportedOperation
524         | errno == eNOSPC          = ResourceExhausted
525         | errno == eNOSR           = ResourceExhausted
526         | errno == eNOSTR          = InvalidArgument
527         | errno == eNOSYS          = UnsupportedOperation
528         | errno == eNOTBLK         = InvalidArgument
529         | errno == eNOTCONN        = InvalidArgument
530         | errno == eNOTDIR         = InappropriateType
531         | errno == eNOTEMPTY       = UnsatisfiedConstraints
532         | errno == eNOTSOCK        = InvalidArgument
533         | errno == eNOTTY          = IllegalOperation
534         | errno == eNXIO           = NoSuchThing
535         | errno == eOPNOTSUPP      = UnsupportedOperation
536         | errno == ePERM           = PermissionDenied
537         | errno == ePFNOSUPPORT    = UnsupportedOperation
538         | errno == ePIPE           = ResourceVanished
539         | errno == ePROCLIM        = PermissionDenied
540         | errno == ePROCUNAVAIL    = UnsupportedOperation
541         | errno == ePROGMISMATCH   = ProtocolError
542         | errno == ePROGUNAVAIL    = UnsupportedOperation
543         | errno == ePROTO          = ProtocolError
544         | errno == ePROTONOSUPPORT = ProtocolError
545         | errno == ePROTOTYPE      = ProtocolError
546         | errno == eRANGE          = UnsupportedOperation
547         | errno == eREMCHG         = ResourceVanished
548         | errno == eREMOTE         = IllegalOperation
549         | errno == eROFS           = PermissionDenied
550         | errno == eRPCMISMATCH    = ProtocolError
551         | errno == eRREMOTE        = IllegalOperation
552         | errno == eSHUTDOWN       = IllegalOperation
553         | errno == eSOCKTNOSUPPORT = UnsupportedOperation
554         | errno == eSPIPE          = UnsupportedOperation
555         | errno == eSRCH           = NoSuchThing
556         | errno == eSRMNT          = UnsatisfiedConstraints
557         | errno == eSTALE          = ResourceVanished
558         | errno == eTIME           = TimeExpired
559         | errno == eTIMEDOUT       = TimeExpired
560         | errno == eTOOMANYREFS    = ResourceExhausted
561         | errno == eTXTBSY         = ResourceBusy
562         | errno == eUSERS          = ResourceExhausted
563         | errno == eWOULDBLOCK     = OtherError
564         | errno == eXDEV           = UnsupportedOperation
565         | otherwise                = OtherError
566 #else
567     return (userError (loc ++ ": " ++ str ++ maybe "" (": "++) maybeName))
568 #endif
569
570 foreign import ccall unsafe "string.h" strerror :: Errno -> IO (Ptr CChar)