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 CCONST_XXX definitions from that configure
87 -- system dependent imports
88 -- ------------------------
90 -- GHC allows us to get at the guts inside IO errors/exceptions
92 #if __GLASGOW_HASKELL__
93 import GHC.IOBase (IOException(..), IOErrorType(..))
94 #endif /* __GLASGOW_HASKELL__ */
100 import Foreign.Storable
102 import Foreign.C.Types
103 import Foreign.C.String
104 import Foreign.Marshal.Error ( void )
107 #if __GLASGOW_HASKELL__
113 import System.IO ( IOError, Handle, ioError )
114 import System.IO.Unsafe ( unsafePerformIO )
120 -- import of C function that gives address of errno
121 -- This function exists because errno is a variable on some systems, but on
122 -- Windows it is a macro for a function...
123 -- [yes, global variables and thread safety don't really go hand-in-hand. -- sof]
124 foreign import ccall unsafe "HsBase.h ghcErrno" _errno :: Ptr CInt
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
156 e2BIG = Errno (CCONST_E2BIG)
157 eACCES = Errno (CCONST_EACCES)
158 eADDRINUSE = Errno (CCONST_EADDRINUSE)
159 eADDRNOTAVAIL = Errno (CCONST_EADDRNOTAVAIL)
160 eADV = Errno (CCONST_EADV)
161 eAFNOSUPPORT = Errno (CCONST_EAFNOSUPPORT)
162 eAGAIN = Errno (CCONST_EAGAIN)
163 eALREADY = Errno (CCONST_EALREADY)
164 eBADF = Errno (CCONST_EBADF)
165 eBADMSG = Errno (CCONST_EBADMSG)
166 eBADRPC = Errno (CCONST_EBADRPC)
167 eBUSY = Errno (CCONST_EBUSY)
168 eCHILD = Errno (CCONST_ECHILD)
169 eCOMM = Errno (CCONST_ECOMM)
170 eCONNABORTED = Errno (CCONST_ECONNABORTED)
171 eCONNREFUSED = Errno (CCONST_ECONNREFUSED)
172 eCONNRESET = Errno (CCONST_ECONNRESET)
173 eDEADLK = Errno (CCONST_EDEADLK)
174 eDESTADDRREQ = Errno (CCONST_EDESTADDRREQ)
175 eDIRTY = Errno (CCONST_EDIRTY)
176 eDOM = Errno (CCONST_EDOM)
177 eDQUOT = Errno (CCONST_EDQUOT)
178 eEXIST = Errno (CCONST_EEXIST)
179 eFAULT = Errno (CCONST_EFAULT)
180 eFBIG = Errno (CCONST_EFBIG)
181 eFTYPE = Errno (CCONST_EFTYPE)
182 eHOSTDOWN = Errno (CCONST_EHOSTDOWN)
183 eHOSTUNREACH = Errno (CCONST_EHOSTUNREACH)
184 eIDRM = Errno (CCONST_EIDRM)
185 eILSEQ = Errno (CCONST_EILSEQ)
186 eINPROGRESS = Errno (CCONST_EINPROGRESS)
187 eINTR = Errno (CCONST_EINTR)
188 eINVAL = Errno (CCONST_EINVAL)
189 eIO = Errno (CCONST_EIO)
190 eISCONN = Errno (CCONST_EISCONN)
191 eISDIR = Errno (CCONST_EISDIR)
192 eLOOP = Errno (CCONST_ELOOP)
193 eMFILE = Errno (CCONST_EMFILE)
194 eMLINK = Errno (CCONST_EMLINK)
195 eMSGSIZE = Errno (CCONST_EMSGSIZE)
196 eMULTIHOP = Errno (CCONST_EMULTIHOP)
197 eNAMETOOLONG = Errno (CCONST_ENAMETOOLONG)
198 eNETDOWN = Errno (CCONST_ENETDOWN)
199 eNETRESET = Errno (CCONST_ENETRESET)
200 eNETUNREACH = Errno (CCONST_ENETUNREACH)
201 eNFILE = Errno (CCONST_ENFILE)
202 eNOBUFS = Errno (CCONST_ENOBUFS)
203 eNODATA = Errno (CCONST_ENODATA)
204 eNODEV = Errno (CCONST_ENODEV)
205 eNOENT = Errno (CCONST_ENOENT)
206 eNOEXEC = Errno (CCONST_ENOEXEC)
207 eNOLCK = Errno (CCONST_ENOLCK)
208 eNOLINK = Errno (CCONST_ENOLINK)
209 eNOMEM = Errno (CCONST_ENOMEM)
210 eNOMSG = Errno (CCONST_ENOMSG)
211 eNONET = Errno (CCONST_ENONET)
212 eNOPROTOOPT = Errno (CCONST_ENOPROTOOPT)
213 eNOSPC = Errno (CCONST_ENOSPC)
214 eNOSR = Errno (CCONST_ENOSR)
215 eNOSTR = Errno (CCONST_ENOSTR)
216 eNOSYS = Errno (CCONST_ENOSYS)
217 eNOTBLK = Errno (CCONST_ENOTBLK)
218 eNOTCONN = Errno (CCONST_ENOTCONN)
219 eNOTDIR = Errno (CCONST_ENOTDIR)
220 eNOTEMPTY = Errno (CCONST_ENOTEMPTY)
221 eNOTSOCK = Errno (CCONST_ENOTSOCK)
222 eNOTTY = Errno (CCONST_ENOTTY)
223 eNXIO = Errno (CCONST_ENXIO)
224 eOPNOTSUPP = Errno (CCONST_EOPNOTSUPP)
225 ePERM = Errno (CCONST_EPERM)
226 ePFNOSUPPORT = Errno (CCONST_EPFNOSUPPORT)
227 ePIPE = Errno (CCONST_EPIPE)
228 ePROCLIM = Errno (CCONST_EPROCLIM)
229 ePROCUNAVAIL = Errno (CCONST_EPROCUNAVAIL)
230 ePROGMISMATCH = Errno (CCONST_EPROGMISMATCH)
231 ePROGUNAVAIL = Errno (CCONST_EPROGUNAVAIL)
232 ePROTO = Errno (CCONST_EPROTO)
233 ePROTONOSUPPORT = Errno (CCONST_EPROTONOSUPPORT)
234 ePROTOTYPE = Errno (CCONST_EPROTOTYPE)
235 eRANGE = Errno (CCONST_ERANGE)
236 eREMCHG = Errno (CCONST_EREMCHG)
237 eREMOTE = Errno (CCONST_EREMOTE)
238 eROFS = Errno (CCONST_EROFS)
239 eRPCMISMATCH = Errno (CCONST_ERPCMISMATCH)
240 eRREMOTE = Errno (CCONST_ERREMOTE)
241 eSHUTDOWN = Errno (CCONST_ESHUTDOWN)
242 eSOCKTNOSUPPORT = Errno (CCONST_ESOCKTNOSUPPORT)
243 eSPIPE = Errno (CCONST_ESPIPE)
244 eSRCH = Errno (CCONST_ESRCH)
245 eSRMNT = Errno (CCONST_ESRMNT)
246 eSTALE = Errno (CCONST_ESTALE)
247 eTIME = Errno (CCONST_ETIME)
248 eTIMEDOUT = Errno (CCONST_ETIMEDOUT)
249 eTOOMANYREFS = Errno (CCONST_ETOOMANYREFS)
250 eTXTBSY = Errno (CCONST_ETXTBSY)
251 eUSERS = Errno (CCONST_EUSERS)
252 eWOULDBLOCK = Errno (CCONST_EWOULDBLOCK)
253 eXDEV = Errno (CCONST_EXDEV)
255 -- checks whether the given errno value is supported on the current
258 isValidErrno :: Errno -> Bool
260 -- the configure script sets all invalid "errno"s to -1
262 isValidErrno (Errno errno) = errno /= -1
265 -- access to the current thread's "errno" value
266 -- --------------------------------------------
268 -- yield the current thread's "errno" value
271 getErrno = do e <- peek _errno; return (Errno e)
273 -- set the current thread's "errno" value to 0
276 resetErrno = poke _errno 0
279 -- throw current "errno" value
280 -- ---------------------------
282 -- the common case: throw an IO error based on a textual description
283 -- of the error location and the current thread's "errno" value
285 throwErrno :: String -> IO a
289 ioError (errnoToIOError loc errno Nothing Nothing)
292 -- guards for IO operations that may fail
293 -- --------------------------------------
295 -- guard an IO operation and throw an "errno" based exception of the result
296 -- value of the IO operation meets the given predicate
298 throwErrnoIf :: (a -> Bool) -> String -> IO a -> IO a
299 throwErrnoIf pred loc f =
302 if pred res then throwErrno loc else return res
304 -- as `throwErrnoIf', but discards the result
306 throwErrnoIf_ :: (a -> Bool) -> String -> IO a -> IO ()
307 throwErrnoIf_ pred loc f = void $ throwErrnoIf pred loc f
309 -- as `throwErrnoIf', but retries interrupted IO operations (ie, those whose
312 throwErrnoIfRetry :: (a -> Bool) -> String -> IO a -> IO a
313 throwErrnoIfRetry pred loc f =
320 then throwErrnoIfRetry pred loc f
324 -- as `throwErrnoIfRetry', but checks for operations that would block and
325 -- executes an alternative action in that case.
327 throwErrnoIfRetryMayBlock :: (a -> Bool) -> String -> IO a -> IO b -> IO a
328 throwErrnoIfRetryMayBlock pred loc f on_block =
335 then throwErrnoIfRetryMayBlock pred loc f on_block
336 else if err == eWOULDBLOCK || err == eAGAIN
337 then do on_block; throwErrnoIfRetryMayBlock pred loc f on_block
341 -- as `throwErrnoIfRetry', but discards the result
343 throwErrnoIfRetry_ :: (a -> Bool) -> String -> IO a -> IO ()
344 throwErrnoIfRetry_ pred loc f = void $ throwErrnoIfRetry pred loc f
346 -- as `throwErrnoIfRetryMayBlock', but discards the result
348 throwErrnoIfRetryMayBlock_ :: (a -> Bool) -> String -> IO a -> IO b -> IO ()
349 throwErrnoIfRetryMayBlock_ pred loc f on_block
350 = void $ throwErrnoIfRetryMayBlock pred loc f on_block
352 -- throws "errno" if a result of "-1" is returned
354 throwErrnoIfMinus1 :: Num a => String -> IO a -> IO a
355 throwErrnoIfMinus1 = throwErrnoIf (== -1)
357 -- as `throwErrnoIfMinus1', but discards the result
359 throwErrnoIfMinus1_ :: Num a => String -> IO a -> IO ()
360 throwErrnoIfMinus1_ = throwErrnoIf_ (== -1)
362 -- throws "errno" if a result of "-1" is returned, but retries in case of an
363 -- interrupted operation
365 throwErrnoIfMinus1Retry :: Num a => String -> IO a -> IO a
366 throwErrnoIfMinus1Retry = throwErrnoIfRetry (== -1)
368 -- as `throwErrnoIfMinus1', but discards the result
370 throwErrnoIfMinus1Retry_ :: Num a => String -> IO a -> IO ()
371 throwErrnoIfMinus1Retry_ = throwErrnoIfRetry_ (== -1)
373 -- as throwErrnoIfMinus1Retry, but checks for operations that would block
375 throwErrnoIfMinus1RetryMayBlock :: Num a => String -> IO a -> IO b -> IO a
376 throwErrnoIfMinus1RetryMayBlock = throwErrnoIfRetryMayBlock (== -1)
378 -- as `throwErrnoIfMinus1RetryMayBlock', but discards the result
380 throwErrnoIfMinus1RetryMayBlock_ :: Num a => String -> IO a -> IO b -> IO ()
381 throwErrnoIfMinus1RetryMayBlock_ = throwErrnoIfRetryMayBlock_ (== -1)
383 -- throws "errno" if a result of a NULL pointer is returned
385 throwErrnoIfNull :: String -> IO (Ptr a) -> IO (Ptr a)
386 throwErrnoIfNull = throwErrnoIf (== nullPtr)
388 -- throws "errno" if a result of a NULL pointer is returned, but retries in
389 -- case of an interrupted operation
391 throwErrnoIfNullRetry :: String -> IO (Ptr a) -> IO (Ptr a)
392 throwErrnoIfNullRetry = throwErrnoIfRetry (== nullPtr)
394 -- as throwErrnoIfNullRetry, but checks for operations that would block
396 throwErrnoIfNullRetryMayBlock :: String -> IO (Ptr a) -> IO b -> IO (Ptr a)
397 throwErrnoIfNullRetryMayBlock = throwErrnoIfRetryMayBlock (== nullPtr)
399 -- conversion of an "errno" value into IO error
400 -- --------------------------------------------
402 -- convert a location string, an "errno" value, an optional handle,
403 -- and an optional filename into a matching IO error
405 errnoToIOError :: String -> Errno -> Maybe Handle -> Maybe String -> IOError
406 errnoToIOError loc errno maybeHdl maybeName = unsafePerformIO $ do
407 str <- strerror errno >>= peekCString
408 #if __GLASGOW_HASKELL__
409 return (IOError maybeHdl errType loc str maybeName)
412 | errno == eOK = OtherError
413 | errno == e2BIG = ResourceExhausted
414 | errno == eACCES = PermissionDenied
415 | errno == eADDRINUSE = ResourceBusy
416 | errno == eADDRNOTAVAIL = UnsupportedOperation
417 | errno == eADV = OtherError
418 | errno == eAFNOSUPPORT = UnsupportedOperation
419 | errno == eAGAIN = ResourceExhausted
420 | errno == eALREADY = AlreadyExists
421 | errno == eBADF = OtherError
422 | errno == eBADMSG = InappropriateType
423 | errno == eBADRPC = OtherError
424 | errno == eBUSY = ResourceBusy
425 | errno == eCHILD = NoSuchThing
426 | errno == eCOMM = ResourceVanished
427 | errno == eCONNABORTED = OtherError
428 | errno == eCONNREFUSED = NoSuchThing
429 | errno == eCONNRESET = ResourceVanished
430 | errno == eDEADLK = ResourceBusy
431 | errno == eDESTADDRREQ = InvalidArgument
432 | errno == eDIRTY = UnsatisfiedConstraints
433 | errno == eDOM = InvalidArgument
434 | errno == eDQUOT = PermissionDenied
435 | errno == eEXIST = AlreadyExists
436 | errno == eFAULT = OtherError
437 | errno == eFBIG = PermissionDenied
438 | errno == eFTYPE = InappropriateType
439 | errno == eHOSTDOWN = NoSuchThing
440 | errno == eHOSTUNREACH = NoSuchThing
441 | errno == eIDRM = ResourceVanished
442 | errno == eILSEQ = InvalidArgument
443 | errno == eINPROGRESS = AlreadyExists
444 | errno == eINTR = Interrupted
445 | errno == eINVAL = InvalidArgument
446 | errno == eIO = HardwareFault
447 | errno == eISCONN = AlreadyExists
448 | errno == eISDIR = InappropriateType
449 | errno == eLOOP = InvalidArgument
450 | errno == eMFILE = ResourceExhausted
451 | errno == eMLINK = ResourceExhausted
452 | errno == eMSGSIZE = ResourceExhausted
453 | errno == eMULTIHOP = UnsupportedOperation
454 | errno == eNAMETOOLONG = InvalidArgument
455 | errno == eNETDOWN = ResourceVanished
456 | errno == eNETRESET = ResourceVanished
457 | errno == eNETUNREACH = NoSuchThing
458 | errno == eNFILE = ResourceExhausted
459 | errno == eNOBUFS = ResourceExhausted
460 | errno == eNODATA = NoSuchThing
461 | errno == eNODEV = UnsupportedOperation
462 | errno == eNOENT = NoSuchThing
463 | errno == eNOEXEC = InvalidArgument
464 | errno == eNOLCK = ResourceExhausted
465 | errno == eNOLINK = ResourceVanished
466 | errno == eNOMEM = ResourceExhausted
467 | errno == eNOMSG = NoSuchThing
468 | errno == eNONET = NoSuchThing
469 | errno == eNOPROTOOPT = UnsupportedOperation
470 | errno == eNOSPC = ResourceExhausted
471 | errno == eNOSR = ResourceExhausted
472 | errno == eNOSTR = InvalidArgument
473 | errno == eNOSYS = UnsupportedOperation
474 | errno == eNOTBLK = InvalidArgument
475 | errno == eNOTCONN = InvalidArgument
476 | errno == eNOTDIR = InappropriateType
477 | errno == eNOTEMPTY = UnsatisfiedConstraints
478 | errno == eNOTSOCK = InvalidArgument
479 | errno == eNOTTY = IllegalOperation
480 | errno == eNXIO = NoSuchThing
481 | errno == eOPNOTSUPP = UnsupportedOperation
482 | errno == ePERM = PermissionDenied
483 | errno == ePFNOSUPPORT = UnsupportedOperation
484 | errno == ePIPE = ResourceVanished
485 | errno == ePROCLIM = PermissionDenied
486 | errno == ePROCUNAVAIL = UnsupportedOperation
487 | errno == ePROGMISMATCH = ProtocolError
488 | errno == ePROGUNAVAIL = UnsupportedOperation
489 | errno == ePROTO = ProtocolError
490 | errno == ePROTONOSUPPORT = ProtocolError
491 | errno == ePROTOTYPE = ProtocolError
492 | errno == eRANGE = UnsupportedOperation
493 | errno == eREMCHG = ResourceVanished
494 | errno == eREMOTE = IllegalOperation
495 | errno == eROFS = PermissionDenied
496 | errno == eRPCMISMATCH = ProtocolError
497 | errno == eRREMOTE = IllegalOperation
498 | errno == eSHUTDOWN = IllegalOperation
499 | errno == eSOCKTNOSUPPORT = UnsupportedOperation
500 | errno == eSPIPE = UnsupportedOperation
501 | errno == eSRCH = NoSuchThing
502 | errno == eSRMNT = UnsatisfiedConstraints
503 | errno == eSTALE = ResourceVanished
504 | errno == eTIME = TimeExpired
505 | errno == eTIMEDOUT = TimeExpired
506 | errno == eTOOMANYREFS = ResourceExhausted
507 | errno == eTXTBSY = ResourceBusy
508 | errno == eUSERS = ResourceExhausted
509 | errno == eWOULDBLOCK = OtherError
510 | errno == eXDEV = UnsupportedOperation
511 | otherwise = OtherError
513 return (userError (loc ++ ": " ++ str ++ maybe "" (": "++) maybeName))
516 foreign import ccall unsafe "string.h" strerror :: Errno -> IO (Ptr CChar)