1 {-# OPTIONS -fno-implicit-prelude -#include "HsCore.h" #-}
2 -----------------------------------------------------------------------------
4 -- Module : Foreign.C.Error
5 -- Copyright : (c) The FFI task force 2001
6 -- License : BSD-style (see the file libraries/core/LICENSE)
8 -- Maintainer : ffi@haskell.org
9 -- Stability : provisional
10 -- Portability : portable
12 -- $Id: Error.hs,v 1.3 2001/07/31 12:59:30 simonmar Exp $
14 -- C-specific Marshalling support: Handling of C "errno" error codes
16 -----------------------------------------------------------------------------
18 module Foreign.C.Error (
20 -- Haskell representation for "errno" values
22 Errno(..), -- instance: Eq
23 eOK, e2BIG, eACCES, eADDRINUSE, eADDRNOTAVAIL, eADV, eAFNOSUPPORT, eAGAIN,
24 eALREADY, eBADF, eBADMSG, eBADRPC, eBUSY, eCHILD, eCOMM, eCONNABORTED,
25 eCONNREFUSED, eCONNRESET, eDEADLK, eDESTADDRREQ, eDIRTY, eDOM, eDQUOT,
26 eEXIST, eFAULT, eFBIG, eFTYPE, eHOSTDOWN, eHOSTUNREACH, eIDRM, eILSEQ,
27 eINPROGRESS, eINTR, eINVAL, eIO, eISCONN, eISDIR, eLOOP, eMFILE, eMLINK,
28 eMSGSIZE, eMULTIHOP, eNAMETOOLONG, eNETDOWN, eNETRESET, eNETUNREACH,
29 eNFILE, eNOBUFS, eNODATA, eNODEV, eNOENT, eNOEXEC, eNOLCK, eNOLINK,
30 eNOMEM, eNOMSG, eNONET, eNOPROTOOPT, eNOSPC, eNOSR, eNOSTR, eNOSYS,
31 eNOTBLK, eNOTCONN, eNOTDIR, eNOTEMPTY, eNOTSOCK, eNOTTY, eNXIO,
32 eOPNOTSUPP, ePERM, ePFNOSUPPORT, ePIPE, ePROCLIM, ePROCUNAVAIL,
33 ePROGMISMATCH, ePROGUNAVAIL, ePROTO, ePROTONOSUPPORT, ePROTOTYPE,
34 eRANGE, eREMCHG, eREMOTE, eROFS, eRPCMISMATCH, eRREMOTE, eSHUTDOWN,
35 eSOCKTNOSUPPORT, eSPIPE, eSRCH, eSRMNT, eSTALE, eTIME, eTIMEDOUT,
36 eTOOMANYREFS, eTXTBSY, eUSERS, eWOULDBLOCK, eXDEV,
38 isValidErrno, -- :: Errno -> Bool
40 -- access to the current thread's "errno" value
42 getErrno, -- :: IO Errno
43 resetErrno, -- :: IO ()
45 -- conversion of an "errno" value into IO error
47 errnoToIOError, -- :: String -- location
49 -- -> Maybe Handle -- handle
50 -- -> Maybe String -- filename
53 -- throw current "errno" value
55 throwErrno, -- :: String -> IO a
57 -- guards for IO operations that may fail
59 throwErrnoIf, -- :: (a -> Bool) -> String -> IO a -> IO a
60 throwErrnoIf_, -- :: (a -> Bool) -> String -> IO a -> IO ()
61 throwErrnoIfRetry, -- :: (a -> Bool) -> String -> IO a -> IO a
62 throwErrnoIfRetry_, -- :: (a -> Bool) -> String -> IO a -> IO ()
63 throwErrnoIfMinus1, -- :: Num a
64 -- => String -> IO a -> IO a
65 throwErrnoIfMinus1_, -- :: Num a
66 -- => String -> IO a -> IO ()
67 throwErrnoIfMinus1Retry,
69 -- => String -> IO a -> IO a
70 throwErrnoIfMinus1Retry_,
72 -- => String -> IO a -> IO ()
73 throwErrnoIfNull, -- :: String -> IO (Ptr a) -> IO (Ptr a)
74 throwErrnoIfNullRetry,-- :: String -> IO (Ptr a) -> IO (Ptr a)
76 throwErrnoIfRetryMayBlock,
77 throwErrnoIfRetryMayBlock_,
78 throwErrnoIfMinus1RetryMayBlock,
79 throwErrnoIfMinus1RetryMayBlock_,
80 throwErrnoIfNullRetryMayBlock
84 -- this is were we get the CCONST_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 (Exception(..), IOException(..), IOErrorType(..))
96 #endif /* __GLASGOW_HASKELL__ */
103 import Foreign.C.Types
104 import Foreign.C.String
105 import Foreign.Marshal.Error ( void )
108 #if __GLASGOW_HASKELL__
114 import System.IO ( IOError, Handle, ioError )
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 foreign import "ghcErrno" unsafe _errno :: Ptr CInt
125 -- Haskell representation for "errno" values
127 newtype Errno = Errno CInt
129 instance Eq Errno where
130 errno1@(Errno no1) == errno2@(Errno no2)
131 | isValidErrno errno1 && isValidErrno errno2 = no1 == no2
134 -- common "errno" symbols
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, 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
151 -- the CCONST_XXX identifiers are cpp symbols whose value is computed by
155 e2BIG = Errno (CCONST_E2BIG)
156 eACCES = Errno (CCONST_EACCES)
157 eADDRINUSE = Errno (CCONST_EADDRINUSE)
158 eADDRNOTAVAIL = Errno (CCONST_EADDRNOTAVAIL)
159 eADV = Errno (CCONST_EADV)
160 eAFNOSUPPORT = Errno (CCONST_EAFNOSUPPORT)
161 eAGAIN = Errno (CCONST_EAGAIN)
162 eALREADY = Errno (CCONST_EALREADY)
163 eBADF = Errno (CCONST_EBADF)
164 eBADMSG = Errno (CCONST_EBADMSG)
165 eBADRPC = Errno (CCONST_EBADRPC)
166 eBUSY = Errno (CCONST_EBUSY)
167 eCHILD = Errno (CCONST_ECHILD)
168 eCOMM = Errno (CCONST_ECOMM)
169 eCONNABORTED = Errno (CCONST_ECONNABORTED)
170 eCONNREFUSED = Errno (CCONST_ECONNREFUSED)
171 eCONNRESET = Errno (CCONST_ECONNRESET)
172 eDEADLK = Errno (CCONST_EDEADLK)
173 eDESTADDRREQ = Errno (CCONST_EDESTADDRREQ)
174 eDIRTY = Errno (CCONST_EDIRTY)
175 eDOM = Errno (CCONST_EDOM)
176 eDQUOT = Errno (CCONST_EDQUOT)
177 eEXIST = Errno (CCONST_EEXIST)
178 eFAULT = Errno (CCONST_EFAULT)
179 eFBIG = Errno (CCONST_EFBIG)
180 eFTYPE = Errno (CCONST_EFTYPE)
181 eHOSTDOWN = Errno (CCONST_EHOSTDOWN)
182 eHOSTUNREACH = Errno (CCONST_EHOSTUNREACH)
183 eIDRM = Errno (CCONST_EIDRM)
184 eILSEQ = Errno (CCONST_EILSEQ)
185 eINPROGRESS = Errno (CCONST_EINPROGRESS)
186 eINTR = Errno (CCONST_EINTR)
187 eINVAL = Errno (CCONST_EINVAL)
188 eIO = Errno (CCONST_EIO)
189 eISCONN = Errno (CCONST_EISCONN)
190 eISDIR = Errno (CCONST_EISDIR)
191 eLOOP = Errno (CCONST_ELOOP)
192 eMFILE = Errno (CCONST_EMFILE)
193 eMLINK = Errno (CCONST_EMLINK)
194 eMSGSIZE = Errno (CCONST_EMSGSIZE)
195 eMULTIHOP = Errno (CCONST_EMULTIHOP)
196 eNAMETOOLONG = Errno (CCONST_ENAMETOOLONG)
197 eNETDOWN = Errno (CCONST_ENETDOWN)
198 eNETRESET = Errno (CCONST_ENETRESET)
199 eNETUNREACH = Errno (CCONST_ENETUNREACH)
200 eNFILE = Errno (CCONST_ENFILE)
201 eNOBUFS = Errno (CCONST_ENOBUFS)
202 eNODATA = Errno (CCONST_ENODATA)
203 eNODEV = Errno (CCONST_ENODEV)
204 eNOENT = Errno (CCONST_ENOENT)
205 eNOEXEC = Errno (CCONST_ENOEXEC)
206 eNOLCK = Errno (CCONST_ENOLCK)
207 eNOLINK = Errno (CCONST_ENOLINK)
208 eNOMEM = Errno (CCONST_ENOMEM)
209 eNOMSG = Errno (CCONST_ENOMSG)
210 eNONET = Errno (CCONST_ENONET)
211 eNOPROTOOPT = Errno (CCONST_ENOPROTOOPT)
212 eNOSPC = Errno (CCONST_ENOSPC)
213 eNOSR = Errno (CCONST_ENOSR)
214 eNOSTR = Errno (CCONST_ENOSTR)
215 eNOSYS = Errno (CCONST_ENOSYS)
216 eNOTBLK = Errno (CCONST_ENOTBLK)
217 eNOTCONN = Errno (CCONST_ENOTCONN)
218 eNOTDIR = Errno (CCONST_ENOTDIR)
219 eNOTEMPTY = Errno (CCONST_ENOTEMPTY)
220 eNOTSOCK = Errno (CCONST_ENOTSOCK)
221 eNOTTY = Errno (CCONST_ENOTTY)
222 eNXIO = Errno (CCONST_ENXIO)
223 eOPNOTSUPP = Errno (CCONST_EOPNOTSUPP)
224 ePERM = Errno (CCONST_EPERM)
225 ePFNOSUPPORT = Errno (CCONST_EPFNOSUPPORT)
226 ePIPE = Errno (CCONST_EPIPE)
227 ePROCLIM = Errno (CCONST_EPROCLIM)
228 ePROCUNAVAIL = Errno (CCONST_EPROCUNAVAIL)
229 ePROGMISMATCH = Errno (CCONST_EPROGMISMATCH)
230 ePROGUNAVAIL = Errno (CCONST_EPROGUNAVAIL)
231 ePROTO = Errno (CCONST_EPROTO)
232 ePROTONOSUPPORT = Errno (CCONST_EPROTONOSUPPORT)
233 ePROTOTYPE = Errno (CCONST_EPROTOTYPE)
234 eRANGE = Errno (CCONST_ERANGE)
235 eREMCHG = Errno (CCONST_EREMCHG)
236 eREMOTE = Errno (CCONST_EREMOTE)
237 eROFS = Errno (CCONST_EROFS)
238 eRPCMISMATCH = Errno (CCONST_ERPCMISMATCH)
239 eRREMOTE = Errno (CCONST_ERREMOTE)
240 eSHUTDOWN = Errno (CCONST_ESHUTDOWN)
241 eSOCKTNOSUPPORT = Errno (CCONST_ESOCKTNOSUPPORT)
242 eSPIPE = Errno (CCONST_ESPIPE)
243 eSRCH = Errno (CCONST_ESRCH)
244 eSRMNT = Errno (CCONST_ESRMNT)
245 eSTALE = Errno (CCONST_ESTALE)
246 eTIME = Errno (CCONST_ETIME)
247 eTIMEDOUT = Errno (CCONST_ETIMEDOUT)
248 eTOOMANYREFS = Errno (CCONST_ETOOMANYREFS)
249 eTXTBSY = Errno (CCONST_ETXTBSY)
250 eUSERS = Errno (CCONST_EUSERS)
251 eWOULDBLOCK = Errno (CCONST_EWOULDBLOCK)
252 eXDEV = Errno (CCONST_EXDEV)
254 -- checks whether the given errno value is supported on the current
257 isValidErrno :: Errno -> Bool
259 -- the configure script sets all invalid "errno"s to -1
261 isValidErrno (Errno errno) = errno /= -1
264 -- access to the current thread's "errno" value
265 -- --------------------------------------------
267 -- yield the current thread's "errno" value
270 getErrno = do e <- peek _errno; return (Errno e)
272 -- set the current thread's "errno" value to 0
275 resetErrno = poke _errno 0
278 -- throw current "errno" value
279 -- ---------------------------
281 -- the common case: throw an IO error based on a textual description
282 -- of the error location and the current thread's "errno" value
284 throwErrno :: String -> IO a
288 ioError (errnoToIOError loc errno Nothing Nothing)
291 -- guards for IO operations that may fail
292 -- --------------------------------------
294 -- guard an IO operation and throw an "errno" based exception of the result
295 -- value of the IO operation meets the given predicate
297 throwErrnoIf :: (a -> Bool) -> String -> IO a -> IO a
298 throwErrnoIf pred loc f =
301 if pred res then throwErrno loc else return res
303 -- as `throwErrnoIf', but discards the result
305 throwErrnoIf_ :: (a -> Bool) -> String -> IO a -> IO ()
306 throwErrnoIf_ pred loc f = void $ throwErrnoIf pred loc f
308 -- as `throwErrnoIf', but retries interrupted IO operations (ie, those whose
311 throwErrnoIfRetry :: (a -> Bool) -> String -> IO a -> IO a
312 throwErrnoIfRetry pred loc f =
319 then throwErrnoIfRetry pred loc f
323 -- as `throwErrnoIfRetry', but checks for operations that would block and
324 -- executes an alternative action in that case.
326 throwErrnoIfRetryMayBlock :: (a -> Bool) -> String -> IO a -> IO b -> IO a
327 throwErrnoIfRetryMayBlock pred loc f on_block =
334 then throwErrnoIfRetryMayBlock pred loc f on_block
335 else if err == eWOULDBLOCK || err == eAGAIN
336 then do on_block; throwErrnoIfRetryMayBlock pred loc f on_block
340 -- as `throwErrnoIfRetry', but discards the result
342 throwErrnoIfRetry_ :: (a -> Bool) -> String -> IO a -> IO ()
343 throwErrnoIfRetry_ pred loc f = void $ throwErrnoIfRetry pred loc f
345 -- as `throwErrnoIfRetryMayBlock', but discards the result
347 throwErrnoIfRetryMayBlock_ :: (a -> Bool) -> String -> IO a -> IO b -> IO ()
348 throwErrnoIfRetryMayBlock_ pred loc f on_block
349 = void $ throwErrnoIfRetryMayBlock pred loc f on_block
351 -- throws "errno" if a result of "-1" is returned
353 throwErrnoIfMinus1 :: Num a => String -> IO a -> IO a
354 throwErrnoIfMinus1 = throwErrnoIf (== -1)
356 -- as `throwErrnoIfMinus1', but discards the result
358 throwErrnoIfMinus1_ :: Num a => String -> IO a -> IO ()
359 throwErrnoIfMinus1_ = throwErrnoIf_ (== -1)
361 -- throws "errno" if a result of "-1" is returned, but retries in case of an
362 -- interrupted operation
364 throwErrnoIfMinus1Retry :: Num a => String -> IO a -> IO a
365 throwErrnoIfMinus1Retry = throwErrnoIfRetry (== -1)
367 -- as `throwErrnoIfMinus1', but discards the result
369 throwErrnoIfMinus1Retry_ :: Num a => String -> IO a -> IO ()
370 throwErrnoIfMinus1Retry_ = throwErrnoIfRetry_ (== -1)
372 -- as throwErrnoIfMinus1Retry, but checks for operations that would block
374 throwErrnoIfMinus1RetryMayBlock :: Num a => String -> IO a -> IO b -> IO a
375 throwErrnoIfMinus1RetryMayBlock = throwErrnoIfRetryMayBlock (== -1)
377 -- as `throwErrnoIfMinus1RetryMayBlock', but discards the result
379 throwErrnoIfMinus1RetryMayBlock_ :: Num a => String -> IO a -> IO b -> IO ()
380 throwErrnoIfMinus1RetryMayBlock_ = throwErrnoIfRetryMayBlock_ (== -1)
382 -- throws "errno" if a result of a NULL pointer is returned
384 throwErrnoIfNull :: String -> IO (Ptr a) -> IO (Ptr a)
385 throwErrnoIfNull = throwErrnoIf (== nullPtr)
387 -- throws "errno" if a result of a NULL pointer is returned, but retries in
388 -- case of an interrupted operation
390 throwErrnoIfNullRetry :: String -> IO (Ptr a) -> IO (Ptr a)
391 throwErrnoIfNullRetry = throwErrnoIfRetry (== nullPtr)
393 -- as throwErrnoIfNullRetry, but checks for operations that would block
395 throwErrnoIfNullRetryMayBlock :: String -> IO (Ptr a) -> IO b -> IO (Ptr a)
396 throwErrnoIfNullRetryMayBlock = throwErrnoIfRetryMayBlock (== nullPtr)
398 -- conversion of an "errno" value into IO error
399 -- --------------------------------------------
401 -- convert a location string, an "errno" value, an optional handle,
402 -- and an optional filename into a matching IO error
404 errnoToIOError :: String -> Errno -> Maybe Handle -> Maybe String -> IOError
405 errnoToIOError loc errno maybeHdl maybeName = unsafePerformIO $ do
406 str <- strerror errno >>= peekCString
407 #if __GLASGOW_HASKELL__
408 return (IOException (IOError maybeHdl errType loc str maybeName))
411 | errno == eOK = OtherError
412 | errno == e2BIG = ResourceExhausted
413 | errno == eACCES = PermissionDenied
414 | errno == eADDRINUSE = ResourceBusy
415 | errno == eADDRNOTAVAIL = UnsupportedOperation
416 | errno == eADV = OtherError
417 | errno == eAFNOSUPPORT = UnsupportedOperation
418 | errno == eAGAIN = ResourceExhausted
419 | errno == eALREADY = AlreadyExists
420 | errno == eBADF = OtherError
421 | errno == eBADMSG = InappropriateType
422 | errno == eBADRPC = OtherError
423 | errno == eBUSY = ResourceBusy
424 | errno == eCHILD = NoSuchThing
425 | errno == eCOMM = ResourceVanished
426 | errno == eCONNABORTED = OtherError
427 | errno == eCONNREFUSED = NoSuchThing
428 | errno == eCONNRESET = ResourceVanished
429 | errno == eDEADLK = ResourceBusy
430 | errno == eDESTADDRREQ = InvalidArgument
431 | errno == eDIRTY = UnsatisfiedConstraints
432 | errno == eDOM = InvalidArgument
433 | errno == eDQUOT = PermissionDenied
434 | errno == eEXIST = AlreadyExists
435 | errno == eFAULT = OtherError
436 | errno == eFBIG = PermissionDenied
437 | errno == eFTYPE = InappropriateType
438 | errno == eHOSTDOWN = NoSuchThing
439 | errno == eHOSTUNREACH = NoSuchThing
440 | errno == eIDRM = ResourceVanished
441 | errno == eILSEQ = InvalidArgument
442 | errno == eINPROGRESS = AlreadyExists
443 | errno == eINTR = Interrupted
444 | errno == eINVAL = InvalidArgument
445 | errno == eIO = HardwareFault
446 | errno == eISCONN = AlreadyExists
447 | errno == eISDIR = InappropriateType
448 | errno == eLOOP = InvalidArgument
449 | errno == eMFILE = ResourceExhausted
450 | errno == eMLINK = ResourceExhausted
451 | errno == eMSGSIZE = ResourceExhausted
452 | errno == eMULTIHOP = UnsupportedOperation
453 | errno == eNAMETOOLONG = InvalidArgument
454 | errno == eNETDOWN = ResourceVanished
455 | errno == eNETRESET = ResourceVanished
456 | errno == eNETUNREACH = NoSuchThing
457 | errno == eNFILE = ResourceExhausted
458 | errno == eNOBUFS = ResourceExhausted
459 | errno == eNODATA = NoSuchThing
460 | errno == eNODEV = NoSuchThing
461 | errno == eNOENT = NoSuchThing
462 | errno == eNOEXEC = InvalidArgument
463 | errno == eNOLCK = ResourceExhausted
464 | errno == eNOLINK = ResourceVanished
465 | errno == eNOMEM = ResourceExhausted
466 | errno == eNOMSG = NoSuchThing
467 | errno == eNONET = NoSuchThing
468 | errno == eNOPROTOOPT = UnsupportedOperation
469 | errno == eNOSPC = ResourceExhausted
470 | errno == eNOSR = ResourceExhausted
471 | errno == eNOSTR = InvalidArgument
472 | errno == eNOSYS = UnsupportedOperation
473 | errno == eNOTBLK = InvalidArgument
474 | errno == eNOTCONN = InvalidArgument
475 | errno == eNOTDIR = InappropriateType
476 | errno == eNOTEMPTY = UnsatisfiedConstraints
477 | errno == eNOTSOCK = InvalidArgument
478 | errno == eNOTTY = IllegalOperation
479 | errno == eNXIO = NoSuchThing
480 | errno == eOPNOTSUPP = UnsupportedOperation
481 | errno == ePERM = PermissionDenied
482 | errno == ePFNOSUPPORT = UnsupportedOperation
483 | errno == ePIPE = ResourceVanished
484 | errno == ePROCLIM = PermissionDenied
485 | errno == ePROCUNAVAIL = UnsupportedOperation
486 | errno == ePROGMISMATCH = ProtocolError
487 | errno == ePROGUNAVAIL = UnsupportedOperation
488 | errno == ePROTO = ProtocolError
489 | errno == ePROTONOSUPPORT = ProtocolError
490 | errno == ePROTOTYPE = ProtocolError
491 | errno == eRANGE = UnsupportedOperation
492 | errno == eREMCHG = ResourceVanished
493 | errno == eREMOTE = IllegalOperation
494 | errno == eROFS = PermissionDenied
495 | errno == eRPCMISMATCH = ProtocolError
496 | errno == eRREMOTE = IllegalOperation
497 | errno == eSHUTDOWN = IllegalOperation
498 | errno == eSOCKTNOSUPPORT = UnsupportedOperation
499 | errno == eSPIPE = UnsupportedOperation
500 | errno == eSRCH = NoSuchThing
501 | errno == eSRMNT = UnsatisfiedConstraints
502 | errno == eSTALE = ResourceVanished
503 | errno == eTIME = TimeExpired
504 | errno == eTIMEDOUT = TimeExpired
505 | errno == eTOOMANYREFS = ResourceExhausted
506 | errno == eTXTBSY = ResourceBusy
507 | errno == eUSERS = ResourceExhausted
508 | errno == eWOULDBLOCK = OtherError
509 | errno == eXDEV = UnsupportedOperation
510 | otherwise = OtherError
512 return (userError (loc ++ ": " ++ str ++ maybe "" (": "++) maybeName))
515 foreign import unsafe strerror :: Errno -> IO (Ptr CChar)