1 {-# OPTIONS -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 representation for "errno" values
20 Errno(..), -- instance: Eq
21 eOK, e2BIG, eACCES, eADDRINUSE, eADDRNOTAVAIL, eADV, eAFNOSUPPORT, eAGAIN,
22 eALREADY, eBADF, eBADMSG, eBADRPC, eBUSY, eCHILD, eCOMM, eCONNABORTED,
23 eCONNREFUSED, eCONNRESET, eDEADLK, eDESTADDRREQ, eDIRTY, eDOM, eDQUOT,
24 eEXIST, eFAULT, eFBIG, eFTYPE, eHOSTDOWN, eHOSTUNREACH, eIDRM, eILSEQ,
25 eINPROGRESS, eINTR, eINVAL, eIO, eISCONN, eISDIR, eLOOP, eMFILE, eMLINK,
26 eMSGSIZE, eMULTIHOP, eNAMETOOLONG, eNETDOWN, eNETRESET, eNETUNREACH,
27 eNFILE, eNOBUFS, eNODATA, eNODEV, eNOENT, eNOEXEC, eNOLCK, eNOLINK,
28 eNOMEM, eNOMSG, eNONET, eNOPROTOOPT, eNOSPC, eNOSR, eNOSTR, eNOSYS,
29 eNOTBLK, eNOTCONN, eNOTDIR, eNOTEMPTY, eNOTSOCK, eNOTTY, eNXIO,
30 eOPNOTSUPP, ePERM, ePFNOSUPPORT, ePIPE, ePROCLIM, ePROCUNAVAIL,
31 ePROGMISMATCH, ePROGUNAVAIL, ePROTO, ePROTONOSUPPORT, ePROTOTYPE,
32 eRANGE, eREMCHG, eREMOTE, eROFS, eRPCMISMATCH, eRREMOTE, eSHUTDOWN,
33 eSOCKTNOSUPPORT, eSPIPE, eSRCH, eSRMNT, eSTALE, eTIME, eTIMEDOUT,
34 eTOOMANYREFS, eTXTBSY, eUSERS, eWOULDBLOCK, eXDEV,
36 isValidErrno, -- :: Errno -> Bool
38 -- access to the current thread's "errno" value
40 getErrno, -- :: IO Errno
41 resetErrno, -- :: IO ()
43 -- conversion of an "errno" value into IO error
45 errnoToIOError, -- :: String -- location
47 -- -> Maybe Handle -- handle
48 -- -> Maybe String -- filename
51 -- throw current "errno" value
53 throwErrno, -- :: String -> IO a
55 -- guards for IO operations that may fail
57 throwErrnoIf, -- :: (a -> Bool) -> String -> IO a -> IO a
58 throwErrnoIf_, -- :: (a -> Bool) -> String -> IO a -> IO ()
59 throwErrnoIfRetry, -- :: (a -> Bool) -> String -> IO a -> IO a
60 throwErrnoIfRetry_, -- :: (a -> Bool) -> String -> IO a -> IO ()
61 throwErrnoIfMinus1, -- :: Num a
62 -- => String -> IO a -> IO a
63 throwErrnoIfMinus1_, -- :: Num a
64 -- => String -> IO a -> IO ()
65 throwErrnoIfMinus1Retry,
67 -- => String -> IO a -> IO a
68 throwErrnoIfMinus1Retry_,
70 -- => String -> IO a -> IO ()
71 throwErrnoIfNull, -- :: String -> IO (Ptr a) -> IO (Ptr a)
72 throwErrnoIfNullRetry,-- :: String -> IO (Ptr a) -> IO (Ptr a)
74 throwErrnoIfRetryMayBlock,
75 throwErrnoIfRetryMayBlock_,
76 throwErrnoIfMinus1RetryMayBlock,
77 throwErrnoIfMinus1RetryMayBlock_,
78 throwErrnoIfNullRetryMayBlock
82 -- this is were we get the CONST_XXX definitions from that configure
89 -- system dependent imports
90 -- ------------------------
92 -- GHC allows us to get at the guts inside IO errors/exceptions
94 #if __GLASGOW_HASKELL__
95 import GHC.IOBase (IOException(..), IOErrorType(..))
96 #endif /* __GLASGOW_HASKELL__ */
102 import Foreign.Storable
104 import Foreign.C.Types
105 import Foreign.C.String
106 import Foreign.Marshal.Error ( void )
109 #if __GLASGOW_HASKELL__
114 import System.IO ( IOError, Handle, ioError )
115 import System.IO.Unsafe ( unsafePerformIO )
119 {-# CBITS PrelIOUtils.c #-}
126 -- Haskell representation for "errno" values
128 newtype Errno = Errno CInt
130 instance Eq Errno where
131 errno1@(Errno no1) == errno2@(Errno no2)
132 | isValidErrno errno1 && isValidErrno errno2 = no1 == no2
135 -- common "errno" symbols
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
152 -- the cCONST_XXX identifiers are cpp symbols whose value is computed by
159 e2BIG = Errno (CONST_E2BIG)
160 eACCES = Errno (CONST_EACCES)
161 eADDRINUSE = Errno (CONST_EADDRINUSE)
162 eADDRNOTAVAIL = Errno (CONST_EADDRNOTAVAIL)
163 eADV = Errno (CONST_EADV)
164 eAFNOSUPPORT = Errno (CONST_EAFNOSUPPORT)
165 eAGAIN = Errno (CONST_EAGAIN)
166 eALREADY = Errno (CONST_EALREADY)
167 eBADF = Errno (CONST_EBADF)
168 eBADMSG = Errno (CONST_EBADMSG)
169 eBADRPC = Errno (CONST_EBADRPC)
170 eBUSY = Errno (CONST_EBUSY)
171 eCHILD = Errno (CONST_ECHILD)
172 eCOMM = Errno (CONST_ECOMM)
173 eCONNABORTED = Errno (CONST_ECONNABORTED)
174 eCONNREFUSED = Errno (CONST_ECONNREFUSED)
175 eCONNRESET = Errno (CONST_ECONNRESET)
176 eDEADLK = Errno (CONST_EDEADLK)
177 eDESTADDRREQ = Errno (CONST_EDESTADDRREQ)
178 eDIRTY = Errno (CONST_EDIRTY)
179 eDOM = Errno (CONST_EDOM)
180 eDQUOT = Errno (CONST_EDQUOT)
181 eEXIST = Errno (CONST_EEXIST)
182 eFAULT = Errno (CONST_EFAULT)
183 eFBIG = Errno (CONST_EFBIG)
184 eFTYPE = Errno (CONST_EFTYPE)
185 eHOSTDOWN = Errno (CONST_EHOSTDOWN)
186 eHOSTUNREACH = Errno (CONST_EHOSTUNREACH)
187 eIDRM = Errno (CONST_EIDRM)
188 eILSEQ = Errno (CONST_EILSEQ)
189 eINPROGRESS = Errno (CONST_EINPROGRESS)
190 eINTR = Errno (CONST_EINTR)
191 eINVAL = Errno (CONST_EINVAL)
192 eIO = Errno (CONST_EIO)
193 eISCONN = Errno (CONST_EISCONN)
194 eISDIR = Errno (CONST_EISDIR)
195 eLOOP = Errno (CONST_ELOOP)
196 eMFILE = Errno (CONST_EMFILE)
197 eMLINK = Errno (CONST_EMLINK)
198 eMSGSIZE = Errno (CONST_EMSGSIZE)
199 eMULTIHOP = Errno (CONST_EMULTIHOP)
200 eNAMETOOLONG = Errno (CONST_ENAMETOOLONG)
201 eNETDOWN = Errno (CONST_ENETDOWN)
202 eNETRESET = Errno (CONST_ENETRESET)
203 eNETUNREACH = Errno (CONST_ENETUNREACH)
204 eNFILE = Errno (CONST_ENFILE)
205 eNOBUFS = Errno (CONST_ENOBUFS)
206 eNODATA = Errno (CONST_ENODATA)
207 eNODEV = Errno (CONST_ENODEV)
208 eNOENT = Errno (CONST_ENOENT)
209 eNOEXEC = Errno (CONST_ENOEXEC)
210 eNOLCK = Errno (CONST_ENOLCK)
211 eNOLINK = Errno (CONST_ENOLINK)
212 eNOMEM = Errno (CONST_ENOMEM)
213 eNOMSG = Errno (CONST_ENOMSG)
214 eNONET = Errno (CONST_ENONET)
215 eNOPROTOOPT = Errno (CONST_ENOPROTOOPT)
216 eNOSPC = Errno (CONST_ENOSPC)
217 eNOSR = Errno (CONST_ENOSR)
218 eNOSTR = Errno (CONST_ENOSTR)
219 eNOSYS = Errno (CONST_ENOSYS)
220 eNOTBLK = Errno (CONST_ENOTBLK)
221 eNOTCONN = Errno (CONST_ENOTCONN)
222 eNOTDIR = Errno (CONST_ENOTDIR)
223 eNOTEMPTY = Errno (CONST_ENOTEMPTY)
224 eNOTSOCK = Errno (CONST_ENOTSOCK)
225 eNOTTY = Errno (CONST_ENOTTY)
226 eNXIO = Errno (CONST_ENXIO)
227 eOPNOTSUPP = Errno (CONST_EOPNOTSUPP)
228 ePERM = Errno (CONST_EPERM)
229 ePFNOSUPPORT = Errno (CONST_EPFNOSUPPORT)
230 ePIPE = Errno (CONST_EPIPE)
231 ePROCLIM = Errno (CONST_EPROCLIM)
232 ePROCUNAVAIL = Errno (CONST_EPROCUNAVAIL)
233 ePROGMISMATCH = Errno (CONST_EPROGMISMATCH)
234 ePROGUNAVAIL = Errno (CONST_EPROGUNAVAIL)
235 ePROTO = Errno (CONST_EPROTO)
236 ePROTONOSUPPORT = Errno (CONST_EPROTONOSUPPORT)
237 ePROTOTYPE = Errno (CONST_EPROTOTYPE)
238 eRANGE = Errno (CONST_ERANGE)
239 eREMCHG = Errno (CONST_EREMCHG)
240 eREMOTE = Errno (CONST_EREMOTE)
241 eROFS = Errno (CONST_EROFS)
242 eRPCMISMATCH = Errno (CONST_ERPCMISMATCH)
243 eRREMOTE = Errno (CONST_ERREMOTE)
244 eSHUTDOWN = Errno (CONST_ESHUTDOWN)
245 eSOCKTNOSUPPORT = Errno (CONST_ESOCKTNOSUPPORT)
246 eSPIPE = Errno (CONST_ESPIPE)
247 eSRCH = Errno (CONST_ESRCH)
248 eSRMNT = Errno (CONST_ESRMNT)
249 eSTALE = Errno (CONST_ESTALE)
250 eTIME = Errno (CONST_ETIME)
251 eTIMEDOUT = Errno (CONST_ETIMEDOUT)
252 eTOOMANYREFS = Errno (CONST_ETOOMANYREFS)
253 eTXTBSY = Errno (CONST_ETXTBSY)
254 eUSERS = Errno (CONST_EUSERS)
255 eWOULDBLOCK = Errno (CONST_EWOULDBLOCK)
256 eXDEV = Errno (CONST_EXDEV)
259 -- checks whether the given errno value is supported on the current
262 isValidErrno :: Errno -> Bool
264 -- the configure script sets all invalid "errno"s to -1
266 isValidErrno (Errno errno) = errno /= -1
269 -- access to the current thread's "errno" value
270 -- --------------------------------------------
272 -- yield the current thread's "errno" value
276 -- We must call a C function to get the value of errno in general. On
277 -- threaded systems, errno is hidden behind a C macro so that each OS
278 -- thread gets its own copy.
280 getErrno = do e <- peek _errno; return (Errno e)
281 foreign import ccall unsafe "errno.h &errno" _errno :: IO (Ptr CInt)
283 getErrno = do e <- get_errno; return (Errno e)
284 foreign import ccall unsafe "HsBase.h __hscore_get_errno" get_errno :: IO CInt
287 -- set the current thread's "errno" value to 0
291 -- Again, setting errno has to be done via a C function.
293 resetErrno = poke _errno 0
295 resetErrno = set_errno 0
296 foreign import ccall unsafe "HsBase.h __hscore_set_errno" set_errno :: CInt -> IO ()
299 -- throw current "errno" value
300 -- ---------------------------
302 -- the common case: throw an IO error based on a textual description
303 -- of the error location and the current thread's "errno" value
305 throwErrno :: String -> IO a
309 ioError (errnoToIOError loc errno Nothing Nothing)
312 -- guards for IO operations that may fail
313 -- --------------------------------------
315 -- guard an IO operation and throw an "errno" based exception of the result
316 -- value of the IO operation meets the given predicate
318 throwErrnoIf :: (a -> Bool) -> String -> IO a -> IO a
319 throwErrnoIf pred loc f =
322 if pred res then throwErrno loc else return res
324 -- as `throwErrnoIf', but discards the result
326 throwErrnoIf_ :: (a -> Bool) -> String -> IO a -> IO ()
327 throwErrnoIf_ pred loc f = void $ throwErrnoIf pred loc f
329 -- as `throwErrnoIf', but retries interrupted IO operations (ie, those whose
332 throwErrnoIfRetry :: (a -> Bool) -> String -> IO a -> IO a
333 throwErrnoIfRetry pred loc f =
340 then throwErrnoIfRetry pred loc f
344 -- as `throwErrnoIfRetry', but checks for operations that would block and
345 -- executes an alternative action in that case.
347 throwErrnoIfRetryMayBlock :: (a -> Bool) -> String -> IO a -> IO b -> IO a
348 throwErrnoIfRetryMayBlock pred loc f on_block =
355 then throwErrnoIfRetryMayBlock pred loc f on_block
356 else if err == eWOULDBLOCK || err == eAGAIN
357 then do on_block; throwErrnoIfRetryMayBlock pred loc f on_block
361 -- as `throwErrnoIfRetry', but discards the result
363 throwErrnoIfRetry_ :: (a -> Bool) -> String -> IO a -> IO ()
364 throwErrnoIfRetry_ pred loc f = void $ throwErrnoIfRetry pred loc f
366 -- as `throwErrnoIfRetryMayBlock', but discards the result
368 throwErrnoIfRetryMayBlock_ :: (a -> Bool) -> String -> IO a -> IO b -> IO ()
369 throwErrnoIfRetryMayBlock_ pred loc f on_block
370 = void $ throwErrnoIfRetryMayBlock pred loc f on_block
372 -- throws "errno" if a result of "-1" is returned
374 throwErrnoIfMinus1 :: Num a => String -> IO a -> IO a
375 throwErrnoIfMinus1 = throwErrnoIf (== -1)
377 -- as `throwErrnoIfMinus1', but discards the result
379 throwErrnoIfMinus1_ :: Num a => String -> IO a -> IO ()
380 throwErrnoIfMinus1_ = throwErrnoIf_ (== -1)
382 -- throws "errno" if a result of "-1" is returned, but retries in case of an
383 -- interrupted operation
385 throwErrnoIfMinus1Retry :: Num a => String -> IO a -> IO a
386 throwErrnoIfMinus1Retry = throwErrnoIfRetry (== -1)
388 -- as `throwErrnoIfMinus1', but discards the result
390 throwErrnoIfMinus1Retry_ :: Num a => String -> IO a -> IO ()
391 throwErrnoIfMinus1Retry_ = throwErrnoIfRetry_ (== -1)
393 -- as throwErrnoIfMinus1Retry, but checks for operations that would block
395 throwErrnoIfMinus1RetryMayBlock :: Num a => String -> IO a -> IO b -> IO a
396 throwErrnoIfMinus1RetryMayBlock = throwErrnoIfRetryMayBlock (== -1)
398 -- as `throwErrnoIfMinus1RetryMayBlock', but discards the result
400 throwErrnoIfMinus1RetryMayBlock_ :: Num a => String -> IO a -> IO b -> IO ()
401 throwErrnoIfMinus1RetryMayBlock_ = throwErrnoIfRetryMayBlock_ (== -1)
403 -- throws "errno" if a result of a NULL pointer is returned
405 throwErrnoIfNull :: String -> IO (Ptr a) -> IO (Ptr a)
406 throwErrnoIfNull = throwErrnoIf (== nullPtr)
408 -- throws "errno" if a result of a NULL pointer is returned, but retries in
409 -- case of an interrupted operation
411 throwErrnoIfNullRetry :: String -> IO (Ptr a) -> IO (Ptr a)
412 throwErrnoIfNullRetry = throwErrnoIfRetry (== nullPtr)
414 -- as throwErrnoIfNullRetry, but checks for operations that would block
416 throwErrnoIfNullRetryMayBlock :: String -> IO (Ptr a) -> IO b -> IO (Ptr a)
417 throwErrnoIfNullRetryMayBlock = throwErrnoIfRetryMayBlock (== nullPtr)
419 -- conversion of an "errno" value into IO error
420 -- --------------------------------------------
422 -- convert a location string, an "errno" value, an optional handle,
423 -- and an optional filename into a matching IO error
425 errnoToIOError :: String -> Errno -> Maybe Handle -> Maybe String -> IOError
426 errnoToIOError loc errno maybeHdl maybeName = unsafePerformIO $ do
427 str <- strerror errno >>= peekCString
428 #if __GLASGOW_HASKELL__
429 return (IOError maybeHdl errType loc str maybeName)
432 | errno == eOK = OtherError
433 | errno == e2BIG = ResourceExhausted
434 | errno == eACCES = PermissionDenied
435 | errno == eADDRINUSE = ResourceBusy
436 | errno == eADDRNOTAVAIL = UnsupportedOperation
437 | errno == eADV = OtherError
438 | errno == eAFNOSUPPORT = UnsupportedOperation
439 | errno == eAGAIN = ResourceExhausted
440 | errno == eALREADY = AlreadyExists
441 | errno == eBADF = OtherError
442 | errno == eBADMSG = InappropriateType
443 | errno == eBADRPC = OtherError
444 | errno == eBUSY = ResourceBusy
445 | errno == eCHILD = NoSuchThing
446 | errno == eCOMM = ResourceVanished
447 | errno == eCONNABORTED = OtherError
448 | errno == eCONNREFUSED = NoSuchThing
449 | errno == eCONNRESET = ResourceVanished
450 | errno == eDEADLK = ResourceBusy
451 | errno == eDESTADDRREQ = InvalidArgument
452 | errno == eDIRTY = UnsatisfiedConstraints
453 | errno == eDOM = InvalidArgument
454 | errno == eDQUOT = PermissionDenied
455 | errno == eEXIST = AlreadyExists
456 | errno == eFAULT = OtherError
457 | errno == eFBIG = PermissionDenied
458 | errno == eFTYPE = InappropriateType
459 | errno == eHOSTDOWN = NoSuchThing
460 | errno == eHOSTUNREACH = NoSuchThing
461 | errno == eIDRM = ResourceVanished
462 | errno == eILSEQ = InvalidArgument
463 | errno == eINPROGRESS = AlreadyExists
464 | errno == eINTR = Interrupted
465 | errno == eINVAL = InvalidArgument
466 | errno == eIO = HardwareFault
467 | errno == eISCONN = AlreadyExists
468 | errno == eISDIR = InappropriateType
469 | errno == eLOOP = InvalidArgument
470 | errno == eMFILE = ResourceExhausted
471 | errno == eMLINK = ResourceExhausted
472 | errno == eMSGSIZE = ResourceExhausted
473 | errno == eMULTIHOP = UnsupportedOperation
474 | errno == eNAMETOOLONG = InvalidArgument
475 | errno == eNETDOWN = ResourceVanished
476 | errno == eNETRESET = ResourceVanished
477 | errno == eNETUNREACH = NoSuchThing
478 | errno == eNFILE = ResourceExhausted
479 | errno == eNOBUFS = ResourceExhausted
480 | errno == eNODATA = NoSuchThing
481 | errno == eNODEV = UnsupportedOperation
482 | errno == eNOENT = NoSuchThing
483 | errno == eNOEXEC = InvalidArgument
484 | errno == eNOLCK = ResourceExhausted
485 | errno == eNOLINK = ResourceVanished
486 | errno == eNOMEM = ResourceExhausted
487 | errno == eNOMSG = NoSuchThing
488 | errno == eNONET = NoSuchThing
489 | errno == eNOPROTOOPT = UnsupportedOperation
490 | errno == eNOSPC = ResourceExhausted
491 | errno == eNOSR = ResourceExhausted
492 | errno == eNOSTR = InvalidArgument
493 | errno == eNOSYS = UnsupportedOperation
494 | errno == eNOTBLK = InvalidArgument
495 | errno == eNOTCONN = InvalidArgument
496 | errno == eNOTDIR = InappropriateType
497 | errno == eNOTEMPTY = UnsatisfiedConstraints
498 | errno == eNOTSOCK = InvalidArgument
499 | errno == eNOTTY = IllegalOperation
500 | errno == eNXIO = NoSuchThing
501 | errno == eOPNOTSUPP = UnsupportedOperation
502 | errno == ePERM = PermissionDenied
503 | errno == ePFNOSUPPORT = UnsupportedOperation
504 | errno == ePIPE = ResourceVanished
505 | errno == ePROCLIM = PermissionDenied
506 | errno == ePROCUNAVAIL = UnsupportedOperation
507 | errno == ePROGMISMATCH = ProtocolError
508 | errno == ePROGUNAVAIL = UnsupportedOperation
509 | errno == ePROTO = ProtocolError
510 | errno == ePROTONOSUPPORT = ProtocolError
511 | errno == ePROTOTYPE = ProtocolError
512 | errno == eRANGE = UnsupportedOperation
513 | errno == eREMCHG = ResourceVanished
514 | errno == eREMOTE = IllegalOperation
515 | errno == eROFS = PermissionDenied
516 | errno == eRPCMISMATCH = ProtocolError
517 | errno == eRREMOTE = IllegalOperation
518 | errno == eSHUTDOWN = IllegalOperation
519 | errno == eSOCKTNOSUPPORT = UnsupportedOperation
520 | errno == eSPIPE = UnsupportedOperation
521 | errno == eSRCH = NoSuchThing
522 | errno == eSRMNT = UnsatisfiedConstraints
523 | errno == eSTALE = ResourceVanished
524 | errno == eTIME = TimeExpired
525 | errno == eTIMEDOUT = TimeExpired
526 | errno == eTOOMANYREFS = ResourceExhausted
527 | errno == eTXTBSY = ResourceBusy
528 | errno == eUSERS = ResourceExhausted
529 | errno == eWOULDBLOCK = OtherError
530 | errno == eXDEV = UnsupportedOperation
531 | otherwise = OtherError
533 return (userError (loc ++ ": " ++ str ++ maybe "" (": "++) maybeName))
536 foreign import ccall unsafe "string.h" strerror :: Errno -> IO (Ptr CChar)