1 {-# OPTIONS_GHC -fno-implicit-prelude -#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
90 -- this is were we get the CONST_XXX definitions from that configure
94 #include "HsBaseConfig.h"
97 -- system dependent imports
98 -- ------------------------
100 -- GHC allows us to get at the guts inside IO errors/exceptions
102 #if __GLASGOW_HASKELL__
103 import GHC.IOBase (IOException(..), IOErrorType(..))
104 #endif /* __GLASGOW_HASKELL__ */
110 import Foreign.Storable
112 import Foreign.C.Types
113 import Foreign.C.String
114 import Foreign.Marshal.Error ( void )
117 #if __GLASGOW_HASKELL__
122 import System.IO ( Handle )
123 import System.IO.Error ( IOError, ioError )
124 import System.IO.Unsafe ( unsafePerformIO )
128 {-# CFILES cbits/PrelIOUtils.c #-}
135 -- | Haskell representation for @errno@ values.
136 -- The implementation is deliberately exposed, to allow users to add
137 -- their own definitions of 'Errno' values.
139 newtype Errno = Errno CInt
141 instance Eq Errno where
142 errno1@(Errno no1) == errno2@(Errno no2)
143 | isValidErrno errno1 && isValidErrno errno2 = no1 == no2
146 -- common "errno" symbols
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
163 -- the cCONST_XXX identifiers are cpp symbols whose value is computed by
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)
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'.
274 isValidErrno :: Errno -> Bool
276 -- the configure script sets all invalid "errno"s to -1
278 isValidErrno (Errno errno) = errno /= -1
281 -- access to the current thread's "errno" value
282 -- --------------------------------------------
284 -- | Get the current value of @errno@ in the current thread.
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.
292 getErrno = do e <- peek _errno; return (Errno e)
293 foreign import ccall unsafe "errno.h &errno" _errno :: Ptr CInt
295 getErrno = do e <- get_errno; return (Errno e)
296 foreign import ccall unsafe "HsBase.h __hscore_get_errno" get_errno :: IO CInt
299 -- | Reset the current thread\'s @errno@ value to 'eOK'.
303 -- Again, setting errno has to be done via a C function.
305 resetErrno = poke _errno 0
307 resetErrno = set_errno 0
308 foreign import ccall unsafe "HsBase.h __hscore_set_errno" set_errno :: CInt -> IO ()
311 -- throw current "errno" value
312 -- ---------------------------
314 -- | Throw an 'IOError' corresponding to the current value of 'getErrno'.
316 throwErrno :: String -- ^ textual description of the error location
321 ioError (errnoToIOError loc errno Nothing Nothing)
324 -- guards for IO operations that may fail
325 -- --------------------------------------
327 -- | Throw an 'IOError' corresponding to the current value of 'getErrno'
328 -- if the result value of the 'IO' action meets the given predicate.
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
335 throwErrnoIf pred loc f =
338 if pred res then throwErrno loc else return res
340 -- | as 'throwErrnoIf', but discards the result of the 'IO' action after
343 throwErrnoIf_ :: (a -> Bool) -> String -> IO a -> IO ()
344 throwErrnoIf_ pred loc f = void $ throwErrnoIf pred loc f
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.
350 throwErrnoIfRetry :: (a -> Bool) -> String -> IO a -> IO a
351 throwErrnoIfRetry pred loc f =
358 then throwErrnoIfRetry pred loc f
362 -- | as 'throwErrnoIfRetry', but checks for operations that would block and
363 -- executes an alternative action before retrying in that case.
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
373 throwErrnoIfRetryMayBlock pred loc f on_block =
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
386 -- | as 'throwErrnoIfRetry', but discards the result.
388 throwErrnoIfRetry_ :: (a -> Bool) -> String -> IO a -> IO ()
389 throwErrnoIfRetry_ pred loc f = void $ throwErrnoIfRetry pred loc f
391 -- | as 'throwErrnoIfRetryMayBlock', but discards the result.
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
397 -- | Throw an 'IOError' corresponding to the current value of 'getErrno'
398 -- if the 'IO' action returns a result of @-1@.
400 throwErrnoIfMinus1 :: Num a => String -> IO a -> IO a
401 throwErrnoIfMinus1 = throwErrnoIf (== -1)
403 -- | as 'throwErrnoIfMinus1', but discards the result.
405 throwErrnoIfMinus1_ :: Num a => String -> IO a -> IO ()
406 throwErrnoIfMinus1_ = throwErrnoIf_ (== -1)
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.
412 throwErrnoIfMinus1Retry :: Num a => String -> IO a -> IO a
413 throwErrnoIfMinus1Retry = throwErrnoIfRetry (== -1)
415 -- | as 'throwErrnoIfMinus1', but discards the result.
417 throwErrnoIfMinus1Retry_ :: Num a => String -> IO a -> IO ()
418 throwErrnoIfMinus1Retry_ = throwErrnoIfRetry_ (== -1)
420 -- | as 'throwErrnoIfMinus1Retry', but checks for operations that would block.
422 throwErrnoIfMinus1RetryMayBlock :: Num a => String -> IO a -> IO b -> IO a
423 throwErrnoIfMinus1RetryMayBlock = throwErrnoIfRetryMayBlock (== -1)
425 -- | as 'throwErrnoIfMinus1RetryMayBlock', but discards the result.
427 throwErrnoIfMinus1RetryMayBlock_ :: Num a => String -> IO a -> IO b -> IO ()
428 throwErrnoIfMinus1RetryMayBlock_ = throwErrnoIfRetryMayBlock_ (== -1)
430 -- | Throw an 'IOError' corresponding to the current value of 'getErrno'
431 -- if the 'IO' action returns 'nullPtr'.
433 throwErrnoIfNull :: String -> IO (Ptr a) -> IO (Ptr a)
434 throwErrnoIfNull = throwErrnoIf (== nullPtr)
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.
440 throwErrnoIfNullRetry :: String -> IO (Ptr a) -> IO (Ptr a)
441 throwErrnoIfNullRetry = throwErrnoIfRetry (== nullPtr)
443 -- | as 'throwErrnoIfNullRetry', but checks for operations that would block.
445 throwErrnoIfNullRetryMayBlock :: String -> IO (Ptr a) -> IO b -> IO (Ptr a)
446 throwErrnoIfNullRetryMayBlock = throwErrnoIfRetryMayBlock (== nullPtr)
448 -- conversion of an "errno" value into IO error
449 -- --------------------------------------------
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
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
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)
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
567 return (userError (loc ++ ": " ++ str ++ maybe "" (": "++) maybeName))
570 foreign import ccall unsafe "string.h" strerror :: Errno -> IO (Ptr CChar)