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