1 {-# OPTIONS_GHC -XNoImplicitPrelude -#include "HsBase.h" #-}
2 -----------------------------------------------------------------------------
4 -- Module : Foreign.C.Error
5 -- Copyright : (c) The FFI task force 2001
6 -- License : BSD-style (see the file libraries/base/LICENSE)
8 -- Maintainer : ffi@haskell.org
9 -- Stability : provisional
10 -- Portability : portable
12 -- C-specific Marshalling support: Handling of C \"errno\" error codes.
14 -----------------------------------------------------------------------------
16 module Foreign.C.Error (
18 -- * Haskell representations of @errno@ values
20 Errno(..), -- instance: Eq
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,
42 -- ** 'Errno' functions
44 isValidErrno, -- :: Errno -> Bool
46 -- access to the current thread's "errno" value
48 getErrno, -- :: IO Errno
49 resetErrno, -- :: IO ()
51 -- conversion of an "errno" value into IO error
53 errnoToIOError, -- :: String -- location
55 -- -> Maybe Handle -- handle
56 -- -> Maybe String -- filename
59 -- throw current "errno" value
61 throwErrno, -- :: String -> IO a
63 -- ** Guards for IO operations that may fail
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,
75 -- => String -> IO a -> IO a
76 throwErrnoIfMinus1Retry_,
78 -- => String -> IO a -> IO ()
79 throwErrnoIfNull, -- :: String -> IO (Ptr a) -> IO (Ptr a)
80 throwErrnoIfNullRetry,-- :: String -> IO (Ptr a) -> IO (Ptr a)
82 throwErrnoIfRetryMayBlock,
83 throwErrnoIfRetryMayBlock_,
84 throwErrnoIfMinus1RetryMayBlock,
85 throwErrnoIfMinus1RetryMayBlock_,
86 throwErrnoIfNullRetryMayBlock,
92 throwErrnoPathIfMinus1,
93 throwErrnoPathIfMinus1_,
97 -- this is were we get the CONST_XXX definitions from that configure
101 #include "HsBaseConfig.h"
105 import Foreign.C.Types
106 import Foreign.C.String
107 import Foreign.Marshal.Error ( void )
110 #if __GLASGOW_HASKELL__
115 import Hugs.Prelude ( Handle, IOError, ioError )
116 import System.IO.Unsafe ( unsafePerformIO )
118 import System.IO ( Handle )
119 import System.IO.Error ( IOError, ioError )
120 import System.IO.Unsafe ( unsafePerformIO )
121 import Foreign.Storable ( Storable(poke,peek) )
125 {-# CFILES cbits/PrelIOUtils.c #-}
132 -- | Haskell representation for @errno@ values.
133 -- The implementation is deliberately exposed, to allow users to add
134 -- their own definitions of 'Errno' values.
136 newtype Errno = Errno CInt
138 instance Eq Errno where
139 errno1@(Errno no1) == errno2@(Errno no2)
140 | isValidErrno errno1 && isValidErrno errno2 = no1 == no2
143 -- common "errno" symbols
145 eOK, e2BIG, eACCES, eADDRINUSE, eADDRNOTAVAIL, eADV, eAFNOSUPPORT, eAGAIN,
146 eALREADY, eBADF, eBADMSG, eBADRPC, eBUSY, eCHILD, eCOMM, eCONNABORTED,
147 eCONNREFUSED, eCONNRESET, eDEADLK, eDESTADDRREQ, eDIRTY, eDOM, eDQUOT,
148 eEXIST, eFAULT, eFBIG, eFTYPE, eHOSTDOWN, eHOSTUNREACH, eIDRM, eILSEQ,
149 eINPROGRESS, eINTR, eINVAL, eIO, eISCONN, eISDIR, eLOOP, eMFILE, eMLINK,
150 eMSGSIZE, eMULTIHOP, eNAMETOOLONG, eNETDOWN, eNETRESET, eNETUNREACH,
151 eNFILE, eNOBUFS, eNODATA, eNODEV, eNOENT, eNOEXEC, eNOLCK, eNOLINK,
152 eNOMEM, eNOMSG, eNONET, eNOPROTOOPT, eNOSPC, eNOSR, eNOSTR, eNOSYS,
153 eNOTBLK, eNOTCONN, eNOTDIR, eNOTEMPTY, eNOTSOCK, eNOTTY, eNXIO,
154 eOPNOTSUPP, ePERM, ePFNOSUPPORT, ePIPE, ePROCLIM, ePROCUNAVAIL,
155 ePROGMISMATCH, ePROGUNAVAIL, ePROTO, ePROTONOSUPPORT, ePROTOTYPE,
156 eRANGE, eREMCHG, eREMOTE, eROFS, eRPCMISMATCH, eRREMOTE, eSHUTDOWN,
157 eSOCKTNOSUPPORT, eSPIPE, eSRCH, eSRMNT, eSTALE, eTIME, eTIMEDOUT,
158 eTOOMANYREFS, eTXTBSY, eUSERS, eWOULDBLOCK, eXDEV :: Errno
160 -- the cCONST_XXX identifiers are cpp symbols whose value is computed by
167 e2BIG = Errno (CONST_E2BIG)
168 eACCES = Errno (CONST_EACCES)
169 eADDRINUSE = Errno (CONST_EADDRINUSE)
170 eADDRNOTAVAIL = Errno (CONST_EADDRNOTAVAIL)
171 eADV = Errno (CONST_EADV)
172 eAFNOSUPPORT = Errno (CONST_EAFNOSUPPORT)
173 eAGAIN = Errno (CONST_EAGAIN)
174 eALREADY = Errno (CONST_EALREADY)
175 eBADF = Errno (CONST_EBADF)
176 eBADMSG = Errno (CONST_EBADMSG)
177 eBADRPC = Errno (CONST_EBADRPC)
178 eBUSY = Errno (CONST_EBUSY)
179 eCHILD = Errno (CONST_ECHILD)
180 eCOMM = Errno (CONST_ECOMM)
181 eCONNABORTED = Errno (CONST_ECONNABORTED)
182 eCONNREFUSED = Errno (CONST_ECONNREFUSED)
183 eCONNRESET = Errno (CONST_ECONNRESET)
184 eDEADLK = Errno (CONST_EDEADLK)
185 eDESTADDRREQ = Errno (CONST_EDESTADDRREQ)
186 eDIRTY = Errno (CONST_EDIRTY)
187 eDOM = Errno (CONST_EDOM)
188 eDQUOT = Errno (CONST_EDQUOT)
189 eEXIST = Errno (CONST_EEXIST)
190 eFAULT = Errno (CONST_EFAULT)
191 eFBIG = Errno (CONST_EFBIG)
192 eFTYPE = Errno (CONST_EFTYPE)
193 eHOSTDOWN = Errno (CONST_EHOSTDOWN)
194 eHOSTUNREACH = Errno (CONST_EHOSTUNREACH)
195 eIDRM = Errno (CONST_EIDRM)
196 eILSEQ = Errno (CONST_EILSEQ)
197 eINPROGRESS = Errno (CONST_EINPROGRESS)
198 eINTR = Errno (CONST_EINTR)
199 eINVAL = Errno (CONST_EINVAL)
200 eIO = Errno (CONST_EIO)
201 eISCONN = Errno (CONST_EISCONN)
202 eISDIR = Errno (CONST_EISDIR)
203 eLOOP = Errno (CONST_ELOOP)
204 eMFILE = Errno (CONST_EMFILE)
205 eMLINK = Errno (CONST_EMLINK)
206 eMSGSIZE = Errno (CONST_EMSGSIZE)
207 eMULTIHOP = Errno (CONST_EMULTIHOP)
208 eNAMETOOLONG = Errno (CONST_ENAMETOOLONG)
209 eNETDOWN = Errno (CONST_ENETDOWN)
210 eNETRESET = Errno (CONST_ENETRESET)
211 eNETUNREACH = Errno (CONST_ENETUNREACH)
212 eNFILE = Errno (CONST_ENFILE)
213 eNOBUFS = Errno (CONST_ENOBUFS)
214 eNODATA = Errno (CONST_ENODATA)
215 eNODEV = Errno (CONST_ENODEV)
216 eNOENT = Errno (CONST_ENOENT)
217 eNOEXEC = Errno (CONST_ENOEXEC)
218 eNOLCK = Errno (CONST_ENOLCK)
219 eNOLINK = Errno (CONST_ENOLINK)
220 eNOMEM = Errno (CONST_ENOMEM)
221 eNOMSG = Errno (CONST_ENOMSG)
222 eNONET = Errno (CONST_ENONET)
223 eNOPROTOOPT = Errno (CONST_ENOPROTOOPT)
224 eNOSPC = Errno (CONST_ENOSPC)
225 eNOSR = Errno (CONST_ENOSR)
226 eNOSTR = Errno (CONST_ENOSTR)
227 eNOSYS = Errno (CONST_ENOSYS)
228 eNOTBLK = Errno (CONST_ENOTBLK)
229 eNOTCONN = Errno (CONST_ENOTCONN)
230 eNOTDIR = Errno (CONST_ENOTDIR)
231 eNOTEMPTY = Errno (CONST_ENOTEMPTY)
232 eNOTSOCK = Errno (CONST_ENOTSOCK)
233 eNOTTY = Errno (CONST_ENOTTY)
234 eNXIO = Errno (CONST_ENXIO)
235 eOPNOTSUPP = Errno (CONST_EOPNOTSUPP)
236 ePERM = Errno (CONST_EPERM)
237 ePFNOSUPPORT = Errno (CONST_EPFNOSUPPORT)
238 ePIPE = Errno (CONST_EPIPE)
239 ePROCLIM = Errno (CONST_EPROCLIM)
240 ePROCUNAVAIL = Errno (CONST_EPROCUNAVAIL)
241 ePROGMISMATCH = Errno (CONST_EPROGMISMATCH)
242 ePROGUNAVAIL = Errno (CONST_EPROGUNAVAIL)
243 ePROTO = Errno (CONST_EPROTO)
244 ePROTONOSUPPORT = Errno (CONST_EPROTONOSUPPORT)
245 ePROTOTYPE = Errno (CONST_EPROTOTYPE)
246 eRANGE = Errno (CONST_ERANGE)
247 eREMCHG = Errno (CONST_EREMCHG)
248 eREMOTE = Errno (CONST_EREMOTE)
249 eROFS = Errno (CONST_EROFS)
250 eRPCMISMATCH = Errno (CONST_ERPCMISMATCH)
251 eRREMOTE = Errno (CONST_ERREMOTE)
252 eSHUTDOWN = Errno (CONST_ESHUTDOWN)
253 eSOCKTNOSUPPORT = Errno (CONST_ESOCKTNOSUPPORT)
254 eSPIPE = Errno (CONST_ESPIPE)
255 eSRCH = Errno (CONST_ESRCH)
256 eSRMNT = Errno (CONST_ESRMNT)
257 eSTALE = Errno (CONST_ESTALE)
258 eTIME = Errno (CONST_ETIME)
259 eTIMEDOUT = Errno (CONST_ETIMEDOUT)
260 eTOOMANYREFS = Errno (CONST_ETOOMANYREFS)
261 eTXTBSY = Errno (CONST_ETXTBSY)
262 eUSERS = Errno (CONST_EUSERS)
263 eWOULDBLOCK = Errno (CONST_EWOULDBLOCK)
264 eXDEV = Errno (CONST_EXDEV)
267 -- | Yield 'True' if the given 'Errno' value is valid on the system.
268 -- This implies that the 'Eq' instance of 'Errno' is also system dependent
269 -- as it is only defined for valid values of 'Errno'.
271 isValidErrno :: Errno -> Bool
273 -- the configure script sets all invalid "errno"s to -1
275 isValidErrno (Errno errno) = errno /= -1
278 -- access to the current thread's "errno" value
279 -- --------------------------------------------
281 -- | Get the current value of @errno@ in the current thread.
285 -- We must call a C function to get the value of errno in general. On
286 -- threaded systems, errno is hidden behind a C macro so that each OS
287 -- thread gets its own copy.
289 getErrno = do e <- peek _errno; return (Errno e)
290 foreign import ccall unsafe "errno.h &errno" _errno :: Ptr CInt
292 getErrno = do e <- get_errno; return (Errno e)
293 foreign import ccall unsafe "HsBase.h __hscore_get_errno" get_errno :: IO CInt
296 -- | Reset the current thread\'s @errno@ value to 'eOK'.
300 -- Again, setting errno has to be done via a C function.
302 resetErrno = poke _errno 0
304 resetErrno = set_errno 0
305 foreign import ccall unsafe "HsBase.h __hscore_set_errno" set_errno :: CInt -> IO ()
308 -- throw current "errno" value
309 -- ---------------------------
311 -- | Throw an 'IOError' corresponding to the current value of 'getErrno'.
313 throwErrno :: String -- ^ textual description of the error location
318 ioError (errnoToIOError loc errno Nothing Nothing)
321 -- guards for IO operations that may fail
322 -- --------------------------------------
324 -- | Throw an 'IOError' corresponding to the current value of 'getErrno'
325 -- if the result value of the 'IO' action meets the given predicate.
327 throwErrnoIf :: (a -> Bool) -- ^ predicate to apply to the result value
328 -- of the 'IO' operation
329 -> String -- ^ textual description of the location
330 -> IO a -- ^ the 'IO' operation to be executed
332 throwErrnoIf pred loc f =
335 if pred res then throwErrno loc else return res
337 -- | as 'throwErrnoIf', but discards the result of the 'IO' action after
340 throwErrnoIf_ :: (a -> Bool) -> String -> IO a -> IO ()
341 throwErrnoIf_ pred loc f = void $ throwErrnoIf pred loc f
343 -- | as 'throwErrnoIf', but retry the 'IO' action when it yields the
344 -- error code 'eINTR' - this amounts to the standard retry loop for
345 -- interrupted POSIX system calls.
347 throwErrnoIfRetry :: (a -> Bool) -> String -> IO a -> IO a
348 throwErrnoIfRetry pred loc f =
355 then throwErrnoIfRetry pred loc f
359 -- | as 'throwErrnoIfRetry', but checks for operations that would block and
360 -- executes an alternative action before retrying in that case.
362 throwErrnoIfRetryMayBlock
363 :: (a -> Bool) -- ^ predicate to apply to the result value
364 -- of the 'IO' operation
365 -> String -- ^ textual description of the location
366 -> IO a -- ^ the 'IO' operation to be executed
367 -> IO b -- ^ action to execute before retrying if
368 -- an immediate retry would block
370 throwErrnoIfRetryMayBlock pred loc f on_block =
377 then throwErrnoIfRetryMayBlock pred loc f on_block
378 else if err == eWOULDBLOCK || err == eAGAIN
379 then do on_block; throwErrnoIfRetryMayBlock pred loc f on_block
383 -- | as 'throwErrnoIfRetry', but discards the result.
385 throwErrnoIfRetry_ :: (a -> Bool) -> String -> IO a -> IO ()
386 throwErrnoIfRetry_ pred loc f = void $ throwErrnoIfRetry pred loc f
388 -- | as 'throwErrnoIfRetryMayBlock', but discards the result.
390 throwErrnoIfRetryMayBlock_ :: (a -> Bool) -> String -> IO a -> IO b -> IO ()
391 throwErrnoIfRetryMayBlock_ pred loc f on_block
392 = void $ throwErrnoIfRetryMayBlock pred loc f on_block
394 -- | Throw an 'IOError' corresponding to the current value of 'getErrno'
395 -- if the 'IO' action returns a result of @-1@.
397 throwErrnoIfMinus1 :: Num a => String -> IO a -> IO a
398 throwErrnoIfMinus1 = throwErrnoIf (== -1)
400 -- | as 'throwErrnoIfMinus1', but discards the result.
402 throwErrnoIfMinus1_ :: Num a => String -> IO a -> IO ()
403 throwErrnoIfMinus1_ = throwErrnoIf_ (== -1)
405 -- | Throw an 'IOError' corresponding to the current value of 'getErrno'
406 -- if the 'IO' action returns a result of @-1@, but retries in case of
407 -- an interrupted operation.
409 throwErrnoIfMinus1Retry :: Num a => String -> IO a -> IO a
410 throwErrnoIfMinus1Retry = throwErrnoIfRetry (== -1)
412 -- | as 'throwErrnoIfMinus1', but discards the result.
414 throwErrnoIfMinus1Retry_ :: Num a => String -> IO a -> IO ()
415 throwErrnoIfMinus1Retry_ = throwErrnoIfRetry_ (== -1)
417 -- | as 'throwErrnoIfMinus1Retry', but checks for operations that would block.
419 throwErrnoIfMinus1RetryMayBlock :: Num a => String -> IO a -> IO b -> IO a
420 throwErrnoIfMinus1RetryMayBlock = throwErrnoIfRetryMayBlock (== -1)
422 -- | as 'throwErrnoIfMinus1RetryMayBlock', but discards the result.
424 throwErrnoIfMinus1RetryMayBlock_ :: Num a => String -> IO a -> IO b -> IO ()
425 throwErrnoIfMinus1RetryMayBlock_ = throwErrnoIfRetryMayBlock_ (== -1)
427 -- | Throw an 'IOError' corresponding to the current value of 'getErrno'
428 -- if the 'IO' action returns 'nullPtr'.
430 throwErrnoIfNull :: String -> IO (Ptr a) -> IO (Ptr a)
431 throwErrnoIfNull = throwErrnoIf (== nullPtr)
433 -- | Throw an 'IOError' corresponding to the current value of 'getErrno'
434 -- if the 'IO' action returns 'nullPtr',
435 -- but retry in case of an interrupted operation.
437 throwErrnoIfNullRetry :: String -> IO (Ptr a) -> IO (Ptr a)
438 throwErrnoIfNullRetry = throwErrnoIfRetry (== nullPtr)
440 -- | as 'throwErrnoIfNullRetry', but checks for operations that would block.
442 throwErrnoIfNullRetryMayBlock :: String -> IO (Ptr a) -> IO b -> IO (Ptr a)
443 throwErrnoIfNullRetryMayBlock = throwErrnoIfRetryMayBlock (== nullPtr)
445 -- | as 'throwErrno', but exceptions include the given path when appropriate.
447 throwErrnoPath :: String -> FilePath -> IO a
448 throwErrnoPath loc path =
451 ioError (errnoToIOError loc errno Nothing (Just path))
453 -- | as 'throwErrnoIf', but exceptions include the given path when
456 throwErrnoPathIf :: (a -> Bool) -> String -> FilePath -> IO a -> IO a
457 throwErrnoPathIf pred loc path f =
460 if pred res then throwErrnoPath loc path else return res
462 -- | as 'throwErrnoIf_', but exceptions include the given path when
465 throwErrnoPathIf_ :: (a -> Bool) -> String -> FilePath -> IO a -> IO ()
466 throwErrnoPathIf_ pred loc path f = void $ throwErrnoPathIf pred loc path f
468 -- | as 'throwErrnoIfNull', but exceptions include the given path when
471 throwErrnoPathIfNull :: String -> FilePath -> IO (Ptr a) -> IO (Ptr a)
472 throwErrnoPathIfNull = throwErrnoPathIf (== nullPtr)
474 -- | as 'throwErrnoIfMinus1', but exceptions include the given path when
477 throwErrnoPathIfMinus1 :: Num a => String -> FilePath -> IO a -> IO a
478 throwErrnoPathIfMinus1 = throwErrnoPathIf (== -1)
480 -- | as 'throwErrnoIfMinus1_', but exceptions include the given path when
483 throwErrnoPathIfMinus1_ :: Num a => String -> FilePath -> IO a -> IO ()
484 throwErrnoPathIfMinus1_ = throwErrnoPathIf_ (== -1)
486 -- conversion of an "errno" value into IO error
487 -- --------------------------------------------
489 -- | Construct a Haskell 98 I\/O error based on the given 'Errno' value.
490 -- The optional information can be used to improve the accuracy of
493 errnoToIOError :: String -- ^ the location where the error occurred
494 -> Errno -- ^ the error number
495 -> Maybe Handle -- ^ optional handle associated with the error
496 -> Maybe String -- ^ optional filename associated with the error
498 errnoToIOError loc errno maybeHdl maybeName = unsafePerformIO $ do
499 str <- strerror errno >>= peekCString
500 #if __GLASGOW_HASKELL__
501 return (IOError maybeHdl errType loc str maybeName)
504 | errno == eOK = OtherError
505 | errno == e2BIG = ResourceExhausted
506 | errno == eACCES = PermissionDenied
507 | errno == eADDRINUSE = ResourceBusy
508 | errno == eADDRNOTAVAIL = UnsupportedOperation
509 | errno == eADV = OtherError
510 | errno == eAFNOSUPPORT = UnsupportedOperation
511 | errno == eAGAIN = ResourceExhausted
512 | errno == eALREADY = AlreadyExists
513 | errno == eBADF = InvalidArgument
514 | errno == eBADMSG = InappropriateType
515 | errno == eBADRPC = OtherError
516 | errno == eBUSY = ResourceBusy
517 | errno == eCHILD = NoSuchThing
518 | errno == eCOMM = ResourceVanished
519 | errno == eCONNABORTED = OtherError
520 | errno == eCONNREFUSED = NoSuchThing
521 | errno == eCONNRESET = ResourceVanished
522 | errno == eDEADLK = ResourceBusy
523 | errno == eDESTADDRREQ = InvalidArgument
524 | errno == eDIRTY = UnsatisfiedConstraints
525 | errno == eDOM = InvalidArgument
526 | errno == eDQUOT = PermissionDenied
527 | errno == eEXIST = AlreadyExists
528 | errno == eFAULT = OtherError
529 | errno == eFBIG = PermissionDenied
530 | errno == eFTYPE = InappropriateType
531 | errno == eHOSTDOWN = NoSuchThing
532 | errno == eHOSTUNREACH = NoSuchThing
533 | errno == eIDRM = ResourceVanished
534 | errno == eILSEQ = InvalidArgument
535 | errno == eINPROGRESS = AlreadyExists
536 | errno == eINTR = Interrupted
537 | errno == eINVAL = InvalidArgument
538 | errno == eIO = HardwareFault
539 | errno == eISCONN = AlreadyExists
540 | errno == eISDIR = InappropriateType
541 | errno == eLOOP = InvalidArgument
542 | errno == eMFILE = ResourceExhausted
543 | errno == eMLINK = ResourceExhausted
544 | errno == eMSGSIZE = ResourceExhausted
545 | errno == eMULTIHOP = UnsupportedOperation
546 | errno == eNAMETOOLONG = InvalidArgument
547 | errno == eNETDOWN = ResourceVanished
548 | errno == eNETRESET = ResourceVanished
549 | errno == eNETUNREACH = NoSuchThing
550 | errno == eNFILE = ResourceExhausted
551 | errno == eNOBUFS = ResourceExhausted
552 | errno == eNODATA = NoSuchThing
553 | errno == eNODEV = UnsupportedOperation
554 | errno == eNOENT = NoSuchThing
555 | errno == eNOEXEC = InvalidArgument
556 | errno == eNOLCK = ResourceExhausted
557 | errno == eNOLINK = ResourceVanished
558 | errno == eNOMEM = ResourceExhausted
559 | errno == eNOMSG = NoSuchThing
560 | errno == eNONET = NoSuchThing
561 | errno == eNOPROTOOPT = UnsupportedOperation
562 | errno == eNOSPC = ResourceExhausted
563 | errno == eNOSR = ResourceExhausted
564 | errno == eNOSTR = InvalidArgument
565 | errno == eNOSYS = UnsupportedOperation
566 | errno == eNOTBLK = InvalidArgument
567 | errno == eNOTCONN = InvalidArgument
568 | errno == eNOTDIR = InappropriateType
569 | errno == eNOTEMPTY = UnsatisfiedConstraints
570 | errno == eNOTSOCK = InvalidArgument
571 | errno == eNOTTY = IllegalOperation
572 | errno == eNXIO = NoSuchThing
573 | errno == eOPNOTSUPP = UnsupportedOperation
574 | errno == ePERM = PermissionDenied
575 | errno == ePFNOSUPPORT = UnsupportedOperation
576 | errno == ePIPE = ResourceVanished
577 | errno == ePROCLIM = PermissionDenied
578 | errno == ePROCUNAVAIL = UnsupportedOperation
579 | errno == ePROGMISMATCH = ProtocolError
580 | errno == ePROGUNAVAIL = UnsupportedOperation
581 | errno == ePROTO = ProtocolError
582 | errno == ePROTONOSUPPORT = ProtocolError
583 | errno == ePROTOTYPE = ProtocolError
584 | errno == eRANGE = UnsupportedOperation
585 | errno == eREMCHG = ResourceVanished
586 | errno == eREMOTE = IllegalOperation
587 | errno == eROFS = PermissionDenied
588 | errno == eRPCMISMATCH = ProtocolError
589 | errno == eRREMOTE = IllegalOperation
590 | errno == eSHUTDOWN = IllegalOperation
591 | errno == eSOCKTNOSUPPORT = UnsupportedOperation
592 | errno == eSPIPE = UnsupportedOperation
593 | errno == eSRCH = NoSuchThing
594 | errno == eSRMNT = UnsatisfiedConstraints
595 | errno == eSTALE = ResourceVanished
596 | errno == eTIME = TimeExpired
597 | errno == eTIMEDOUT = TimeExpired
598 | errno == eTOOMANYREFS = ResourceExhausted
599 | errno == eTXTBSY = ResourceBusy
600 | errno == eUSERS = ResourceExhausted
601 | errno == eWOULDBLOCK = OtherError
602 | errno == eXDEV = UnsupportedOperation
603 | otherwise = OtherError
605 return (userError (loc ++ ": " ++ str ++ maybe "" (": "++) maybeName))
608 foreign import ccall unsafe "string.h" strerror :: Errno -> IO (Ptr CChar)