X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=Foreign%2FC%2FError.hs;h=9ee64995da8f64f0dca43e7a24bf6c0b8f7cab8a;hb=beaf733bae2acdf2cc1a2b1234e4532a0ccc655d;hp=72cb512d6789cb783f60e0b935ba60c56f0ff193;hpb=36eed61fede3856f9b710dde0871f284d5ec7cc9;p=ghc-base.git diff --git a/Foreign/C/Error.hs b/Foreign/C/Error.hs index 72cb512..9ee6499 100644 --- a/Foreign/C/Error.hs +++ b/Foreign/C/Error.hs @@ -9,15 +9,21 @@ -- Stability : provisional -- Portability : portable -- --- C-specific Marshalling support: Handling of C "errno" error codes +-- C-specific Marshalling support: Handling of C \"errno\" error codes. -- ----------------------------------------------------------------------------- module Foreign.C.Error ( - -- Haskell representation for "errno" values - -- + -- * Haskell representations of @errno@ values + Errno(..), -- instance: Eq + + -- ** Common @errno@ symbols + -- | Different operating systems and\/or C libraries often support + -- different values of @errno@. This module defines the common values, + -- but due to the open definition of 'Errno' users may add definitions + -- which are not predefined. eOK, e2BIG, eACCES, eADDRINUSE, eADDRNOTAVAIL, eADV, eAFNOSUPPORT, eAGAIN, eALREADY, eBADF, eBADMSG, eBADRPC, eBUSY, eCHILD, eCOMM, eCONNABORTED, eCONNREFUSED, eCONNRESET, eDEADLK, eDESTADDRREQ, eDIRTY, eDOM, eDQUOT, @@ -32,6 +38,8 @@ module Foreign.C.Error ( eRANGE, eREMCHG, eREMOTE, eROFS, eRPCMISMATCH, eRREMOTE, eSHUTDOWN, eSOCKTNOSUPPORT, eSPIPE, eSRCH, eSRMNT, eSTALE, eTIME, eTIMEDOUT, eTOOMANYREFS, eTXTBSY, eUSERS, eWOULDBLOCK, eXDEV, + + -- ** 'Errno' functions -- :: Errno isValidErrno, -- :: Errno -> Bool @@ -52,8 +60,8 @@ module Foreign.C.Error ( -- throwErrno, -- :: String -> IO a - -- guards for IO operations that may fail - -- + -- ** Guards for IO operations that may fail + throwErrnoIf, -- :: (a -> Bool) -> String -> IO a -> IO a throwErrnoIf_, -- :: (a -> Bool) -> String -> IO a -> IO () throwErrnoIfRetry, -- :: (a -> Bool) -> String -> IO a -> IO a @@ -79,10 +87,12 @@ module Foreign.C.Error ( ) where --- this is were we get the CCONST_XXX definitions from that configure +-- this is were we get the CONST_XXX definitions from that configure -- calculated for us -- -#include "config.h" +#ifndef __NHC__ +#include "HsBaseConfig.h" +#endif -- system dependent imports -- ------------------------ @@ -90,7 +100,7 @@ module Foreign.C.Error ( -- GHC allows us to get at the guts inside IO errors/exceptions -- #if __GLASGOW_HASKELL__ -import GHC.IOBase (Exception(..), IOException(..), IOErrorType(..)) +import GHC.IOBase (IOException(..), IOErrorType(..)) #endif /* __GLASGOW_HASKELL__ */ @@ -105,7 +115,6 @@ import Foreign.Marshal.Error ( void ) import Data.Maybe #if __GLASGOW_HASKELL__ -import GHC.Storable import GHC.IOBase import GHC.Num import GHC.Base @@ -114,17 +123,18 @@ import System.IO ( IOError, Handle, ioError ) import System.IO.Unsafe ( unsafePerformIO ) #endif +#ifdef __HUGS__ +{-# CFILES cbits/PrelIOUtils.c #-} +#endif + + -- "errno" type -- ------------ --- import of C function that gives address of errno --- This function exists because errno is a variable on some systems, but on --- Windows it is a macro for a function... --- [yes, global variables and thread safety don't really go hand-in-hand. -- sof] -foreign import ccall unsafe "HsBase.h ghcErrno" _errno :: Ptr CInt +-- | Haskell representation for @errno@ values. +-- The implementation is deliberately exposed, to allow users to add +-- their own definitions of 'Errno' values. --- Haskell representation for "errno" values --- newtype Errno = Errno CInt instance Eq Errno where @@ -153,107 +163,112 @@ eOK, e2BIG, eACCES, eADDRINUSE, eADDRNOTAVAIL, eADV, eAFNOSUPPORT, eAGAIN, -- configure -- eOK = Errno 0 -e2BIG = Errno (CCONST_E2BIG) -eACCES = Errno (CCONST_EACCES) -eADDRINUSE = Errno (CCONST_EADDRINUSE) -eADDRNOTAVAIL = Errno (CCONST_EADDRNOTAVAIL) -eADV = Errno (CCONST_EADV) -eAFNOSUPPORT = Errno (CCONST_EAFNOSUPPORT) -eAGAIN = Errno (CCONST_EAGAIN) -eALREADY = Errno (CCONST_EALREADY) -eBADF = Errno (CCONST_EBADF) -eBADMSG = Errno (CCONST_EBADMSG) -eBADRPC = Errno (CCONST_EBADRPC) -eBUSY = Errno (CCONST_EBUSY) -eCHILD = Errno (CCONST_ECHILD) -eCOMM = Errno (CCONST_ECOMM) -eCONNABORTED = Errno (CCONST_ECONNABORTED) -eCONNREFUSED = Errno (CCONST_ECONNREFUSED) -eCONNRESET = Errno (CCONST_ECONNRESET) -eDEADLK = Errno (CCONST_EDEADLK) -eDESTADDRREQ = Errno (CCONST_EDESTADDRREQ) -eDIRTY = Errno (CCONST_EDIRTY) -eDOM = Errno (CCONST_EDOM) -eDQUOT = Errno (CCONST_EDQUOT) -eEXIST = Errno (CCONST_EEXIST) -eFAULT = Errno (CCONST_EFAULT) -eFBIG = Errno (CCONST_EFBIG) -eFTYPE = Errno (CCONST_EFTYPE) -eHOSTDOWN = Errno (CCONST_EHOSTDOWN) -eHOSTUNREACH = Errno (CCONST_EHOSTUNREACH) -eIDRM = Errno (CCONST_EIDRM) -eILSEQ = Errno (CCONST_EILSEQ) -eINPROGRESS = Errno (CCONST_EINPROGRESS) -eINTR = Errno (CCONST_EINTR) -eINVAL = Errno (CCONST_EINVAL) -eIO = Errno (CCONST_EIO) -eISCONN = Errno (CCONST_EISCONN) -eISDIR = Errno (CCONST_EISDIR) -eLOOP = Errno (CCONST_ELOOP) -eMFILE = Errno (CCONST_EMFILE) -eMLINK = Errno (CCONST_EMLINK) -eMSGSIZE = Errno (CCONST_EMSGSIZE) -eMULTIHOP = Errno (CCONST_EMULTIHOP) -eNAMETOOLONG = Errno (CCONST_ENAMETOOLONG) -eNETDOWN = Errno (CCONST_ENETDOWN) -eNETRESET = Errno (CCONST_ENETRESET) -eNETUNREACH = Errno (CCONST_ENETUNREACH) -eNFILE = Errno (CCONST_ENFILE) -eNOBUFS = Errno (CCONST_ENOBUFS) -eNODATA = Errno (CCONST_ENODATA) -eNODEV = Errno (CCONST_ENODEV) -eNOENT = Errno (CCONST_ENOENT) -eNOEXEC = Errno (CCONST_ENOEXEC) -eNOLCK = Errno (CCONST_ENOLCK) -eNOLINK = Errno (CCONST_ENOLINK) -eNOMEM = Errno (CCONST_ENOMEM) -eNOMSG = Errno (CCONST_ENOMSG) -eNONET = Errno (CCONST_ENONET) -eNOPROTOOPT = Errno (CCONST_ENOPROTOOPT) -eNOSPC = Errno (CCONST_ENOSPC) -eNOSR = Errno (CCONST_ENOSR) -eNOSTR = Errno (CCONST_ENOSTR) -eNOSYS = Errno (CCONST_ENOSYS) -eNOTBLK = Errno (CCONST_ENOTBLK) -eNOTCONN = Errno (CCONST_ENOTCONN) -eNOTDIR = Errno (CCONST_ENOTDIR) -eNOTEMPTY = Errno (CCONST_ENOTEMPTY) -eNOTSOCK = Errno (CCONST_ENOTSOCK) -eNOTTY = Errno (CCONST_ENOTTY) -eNXIO = Errno (CCONST_ENXIO) -eOPNOTSUPP = Errno (CCONST_EOPNOTSUPP) -ePERM = Errno (CCONST_EPERM) -ePFNOSUPPORT = Errno (CCONST_EPFNOSUPPORT) -ePIPE = Errno (CCONST_EPIPE) -ePROCLIM = Errno (CCONST_EPROCLIM) -ePROCUNAVAIL = Errno (CCONST_EPROCUNAVAIL) -ePROGMISMATCH = Errno (CCONST_EPROGMISMATCH) -ePROGUNAVAIL = Errno (CCONST_EPROGUNAVAIL) -ePROTO = Errno (CCONST_EPROTO) -ePROTONOSUPPORT = Errno (CCONST_EPROTONOSUPPORT) -ePROTOTYPE = Errno (CCONST_EPROTOTYPE) -eRANGE = Errno (CCONST_ERANGE) -eREMCHG = Errno (CCONST_EREMCHG) -eREMOTE = Errno (CCONST_EREMOTE) -eROFS = Errno (CCONST_EROFS) -eRPCMISMATCH = Errno (CCONST_ERPCMISMATCH) -eRREMOTE = Errno (CCONST_ERREMOTE) -eSHUTDOWN = Errno (CCONST_ESHUTDOWN) -eSOCKTNOSUPPORT = Errno (CCONST_ESOCKTNOSUPPORT) -eSPIPE = Errno (CCONST_ESPIPE) -eSRCH = Errno (CCONST_ESRCH) -eSRMNT = Errno (CCONST_ESRMNT) -eSTALE = Errno (CCONST_ESTALE) -eTIME = Errno (CCONST_ETIME) -eTIMEDOUT = Errno (CCONST_ETIMEDOUT) -eTOOMANYREFS = Errno (CCONST_ETOOMANYREFS) -eTXTBSY = Errno (CCONST_ETXTBSY) -eUSERS = Errno (CCONST_EUSERS) -eWOULDBLOCK = Errno (CCONST_EWOULDBLOCK) -eXDEV = Errno (CCONST_EXDEV) - --- checks whether the given errno value is supported on the current --- architecture +#ifdef __NHC__ +#include "Errno.hs" +#else +e2BIG = Errno (CONST_E2BIG) +eACCES = Errno (CONST_EACCES) +eADDRINUSE = Errno (CONST_EADDRINUSE) +eADDRNOTAVAIL = Errno (CONST_EADDRNOTAVAIL) +eADV = Errno (CONST_EADV) +eAFNOSUPPORT = Errno (CONST_EAFNOSUPPORT) +eAGAIN = Errno (CONST_EAGAIN) +eALREADY = Errno (CONST_EALREADY) +eBADF = Errno (CONST_EBADF) +eBADMSG = Errno (CONST_EBADMSG) +eBADRPC = Errno (CONST_EBADRPC) +eBUSY = Errno (CONST_EBUSY) +eCHILD = Errno (CONST_ECHILD) +eCOMM = Errno (CONST_ECOMM) +eCONNABORTED = Errno (CONST_ECONNABORTED) +eCONNREFUSED = Errno (CONST_ECONNREFUSED) +eCONNRESET = Errno (CONST_ECONNRESET) +eDEADLK = Errno (CONST_EDEADLK) +eDESTADDRREQ = Errno (CONST_EDESTADDRREQ) +eDIRTY = Errno (CONST_EDIRTY) +eDOM = Errno (CONST_EDOM) +eDQUOT = Errno (CONST_EDQUOT) +eEXIST = Errno (CONST_EEXIST) +eFAULT = Errno (CONST_EFAULT) +eFBIG = Errno (CONST_EFBIG) +eFTYPE = Errno (CONST_EFTYPE) +eHOSTDOWN = Errno (CONST_EHOSTDOWN) +eHOSTUNREACH = Errno (CONST_EHOSTUNREACH) +eIDRM = Errno (CONST_EIDRM) +eILSEQ = Errno (CONST_EILSEQ) +eINPROGRESS = Errno (CONST_EINPROGRESS) +eINTR = Errno (CONST_EINTR) +eINVAL = Errno (CONST_EINVAL) +eIO = Errno (CONST_EIO) +eISCONN = Errno (CONST_EISCONN) +eISDIR = Errno (CONST_EISDIR) +eLOOP = Errno (CONST_ELOOP) +eMFILE = Errno (CONST_EMFILE) +eMLINK = Errno (CONST_EMLINK) +eMSGSIZE = Errno (CONST_EMSGSIZE) +eMULTIHOP = Errno (CONST_EMULTIHOP) +eNAMETOOLONG = Errno (CONST_ENAMETOOLONG) +eNETDOWN = Errno (CONST_ENETDOWN) +eNETRESET = Errno (CONST_ENETRESET) +eNETUNREACH = Errno (CONST_ENETUNREACH) +eNFILE = Errno (CONST_ENFILE) +eNOBUFS = Errno (CONST_ENOBUFS) +eNODATA = Errno (CONST_ENODATA) +eNODEV = Errno (CONST_ENODEV) +eNOENT = Errno (CONST_ENOENT) +eNOEXEC = Errno (CONST_ENOEXEC) +eNOLCK = Errno (CONST_ENOLCK) +eNOLINK = Errno (CONST_ENOLINK) +eNOMEM = Errno (CONST_ENOMEM) +eNOMSG = Errno (CONST_ENOMSG) +eNONET = Errno (CONST_ENONET) +eNOPROTOOPT = Errno (CONST_ENOPROTOOPT) +eNOSPC = Errno (CONST_ENOSPC) +eNOSR = Errno (CONST_ENOSR) +eNOSTR = Errno (CONST_ENOSTR) +eNOSYS = Errno (CONST_ENOSYS) +eNOTBLK = Errno (CONST_ENOTBLK) +eNOTCONN = Errno (CONST_ENOTCONN) +eNOTDIR = Errno (CONST_ENOTDIR) +eNOTEMPTY = Errno (CONST_ENOTEMPTY) +eNOTSOCK = Errno (CONST_ENOTSOCK) +eNOTTY = Errno (CONST_ENOTTY) +eNXIO = Errno (CONST_ENXIO) +eOPNOTSUPP = Errno (CONST_EOPNOTSUPP) +ePERM = Errno (CONST_EPERM) +ePFNOSUPPORT = Errno (CONST_EPFNOSUPPORT) +ePIPE = Errno (CONST_EPIPE) +ePROCLIM = Errno (CONST_EPROCLIM) +ePROCUNAVAIL = Errno (CONST_EPROCUNAVAIL) +ePROGMISMATCH = Errno (CONST_EPROGMISMATCH) +ePROGUNAVAIL = Errno (CONST_EPROGUNAVAIL) +ePROTO = Errno (CONST_EPROTO) +ePROTONOSUPPORT = Errno (CONST_EPROTONOSUPPORT) +ePROTOTYPE = Errno (CONST_EPROTOTYPE) +eRANGE = Errno (CONST_ERANGE) +eREMCHG = Errno (CONST_EREMCHG) +eREMOTE = Errno (CONST_EREMOTE) +eROFS = Errno (CONST_EROFS) +eRPCMISMATCH = Errno (CONST_ERPCMISMATCH) +eRREMOTE = Errno (CONST_ERREMOTE) +eSHUTDOWN = Errno (CONST_ESHUTDOWN) +eSOCKTNOSUPPORT = Errno (CONST_ESOCKTNOSUPPORT) +eSPIPE = Errno (CONST_ESPIPE) +eSRCH = Errno (CONST_ESRCH) +eSRMNT = Errno (CONST_ESRMNT) +eSTALE = Errno (CONST_ESTALE) +eTIME = Errno (CONST_ETIME) +eTIMEDOUT = Errno (CONST_ETIMEDOUT) +eTOOMANYREFS = Errno (CONST_ETOOMANYREFS) +eTXTBSY = Errno (CONST_ETXTBSY) +eUSERS = Errno (CONST_EUSERS) +eWOULDBLOCK = Errno (CONST_EWOULDBLOCK) +eXDEV = Errno (CONST_EXDEV) +#endif + +-- | Yield 'True' if the given 'Errno' value is valid on the system. +-- This implies that the 'Eq' instance of 'Errno' is also system dependent +-- as it is only defined for valid values of 'Errno'. -- isValidErrno :: Errno -> Bool -- @@ -265,24 +280,40 @@ isValidErrno (Errno errno) = errno /= -1 -- access to the current thread's "errno" value -- -------------------------------------------- --- yield the current thread's "errno" value +-- | Get the current value of @errno@ in the current thread. -- getErrno :: IO Errno -getErrno = do e <- peek _errno; return (Errno e) --- set the current thread's "errno" value to 0 +-- We must call a C function to get the value of errno in general. On +-- threaded systems, errno is hidden behind a C macro so that each OS +-- thread gets its own copy. +#ifdef __NHC__ +getErrno = do e <- peek _errno; return (Errno e) +foreign import ccall unsafe "errno.h &errno" _errno :: Ptr CInt +#else +getErrno = do e <- get_errno; return (Errno e) +foreign import ccall unsafe "HsBase.h __hscore_get_errno" get_errno :: IO CInt +#endif + +-- | Reset the current thread\'s @errno@ value to 'eOK'. -- resetErrno :: IO () -resetErrno = poke _errno 0 +-- Again, setting errno has to be done via a C function. +#ifdef __NHC__ +resetErrno = poke _errno 0 +#else +resetErrno = set_errno 0 +foreign import ccall unsafe "HsBase.h __hscore_set_errno" set_errno :: CInt -> IO () +#endif -- throw current "errno" value -- --------------------------- --- the common case: throw an IO error based on a textual description --- of the error location and the current thread's "errno" value +-- | Throw an 'IOError' corresponding to the current value of 'getErrno'. -- -throwErrno :: String -> IO a +throwErrno :: String -- ^ textual description of the error location + -> IO a throwErrno loc = do errno <- getErrno @@ -292,22 +323,28 @@ throwErrno loc = -- guards for IO operations that may fail -- -------------------------------------- --- guard an IO operation and throw an "errno" based exception of the result --- value of the IO operation meets the given predicate +-- | Throw an 'IOError' corresponding to the current value of 'getErrno' +-- if the result value of the 'IO' action meets the given predicate. -- -throwErrnoIf :: (a -> Bool) -> String -> IO a -> IO a +throwErrnoIf :: (a -> Bool) -- ^ predicate to apply to the result value + -- of the 'IO' operation + -> String -- ^ textual description of the location + -> IO a -- ^ the 'IO' operation to be executed + -> IO a throwErrnoIf pred loc f = do res <- f if pred res then throwErrno loc else return res --- as `throwErrnoIf', but discards the result +-- | as 'throwErrnoIf', but discards the result of the 'IO' action after +-- error handling. -- -throwErrnoIf_ :: (a -> Bool) -> String -> IO a -> IO () +throwErrnoIf_ :: (a -> Bool) -> String -> IO a -> IO () throwErrnoIf_ pred loc f = void $ throwErrnoIf pred loc f --- as `throwErrnoIf', but retries interrupted IO operations (ie, those whose --- flag `EINTR') +-- | as 'throwErrnoIf', but retry the 'IO' action when it yields the +-- error code 'eINTR' - this amounts to the standard retry loop for +-- interrupted POSIX system calls. -- throwErrnoIfRetry :: (a -> Bool) -> String -> IO a -> IO a throwErrnoIfRetry pred loc f = @@ -321,10 +358,17 @@ throwErrnoIfRetry pred loc f = else throwErrno loc else return res --- as `throwErrnoIfRetry', but checks for operations that would block and --- executes an alternative action in that case. - -throwErrnoIfRetryMayBlock :: (a -> Bool) -> String -> IO a -> IO b -> IO a +-- | as 'throwErrnoIfRetry', but checks for operations that would block and +-- executes an alternative action before retrying in that case. +-- +throwErrnoIfRetryMayBlock + :: (a -> Bool) -- ^ predicate to apply to the result value + -- of the 'IO' operation + -> String -- ^ textual description of the location + -> IO a -- ^ the 'IO' operation to be executed + -> IO b -- ^ action to execute before retrying if + -- an immediate retry would block + -> IO a throwErrnoIfRetryMayBlock pred loc f on_block = do res <- f @@ -338,60 +382,64 @@ throwErrnoIfRetryMayBlock pred loc f on_block = else throwErrno loc else return res --- as `throwErrnoIfRetry', but discards the result +-- | as 'throwErrnoIfRetry', but discards the result. -- throwErrnoIfRetry_ :: (a -> Bool) -> String -> IO a -> IO () throwErrnoIfRetry_ pred loc f = void $ throwErrnoIfRetry pred loc f --- as `throwErrnoIfRetryMayBlock', but discards the result +-- | as 'throwErrnoIfRetryMayBlock', but discards the result. -- throwErrnoIfRetryMayBlock_ :: (a -> Bool) -> String -> IO a -> IO b -> IO () throwErrnoIfRetryMayBlock_ pred loc f on_block = void $ throwErrnoIfRetryMayBlock pred loc f on_block --- throws "errno" if a result of "-1" is returned +-- | Throw an 'IOError' corresponding to the current value of 'getErrno' +-- if the 'IO' action returns a result of @-1@. -- throwErrnoIfMinus1 :: Num a => String -> IO a -> IO a throwErrnoIfMinus1 = throwErrnoIf (== -1) --- as `throwErrnoIfMinus1', but discards the result +-- | as 'throwErrnoIfMinus1', but discards the result. -- throwErrnoIfMinus1_ :: Num a => String -> IO a -> IO () throwErrnoIfMinus1_ = throwErrnoIf_ (== -1) --- throws "errno" if a result of "-1" is returned, but retries in case of an --- interrupted operation +-- | Throw an 'IOError' corresponding to the current value of 'getErrno' +-- if the 'IO' action returns a result of @-1@, but retries in case of +-- an interrupted operation. -- throwErrnoIfMinus1Retry :: Num a => String -> IO a -> IO a throwErrnoIfMinus1Retry = throwErrnoIfRetry (== -1) --- as `throwErrnoIfMinus1', but discards the result +-- | as 'throwErrnoIfMinus1', but discards the result. -- throwErrnoIfMinus1Retry_ :: Num a => String -> IO a -> IO () throwErrnoIfMinus1Retry_ = throwErrnoIfRetry_ (== -1) --- as throwErrnoIfMinus1Retry, but checks for operations that would block +-- | as 'throwErrnoIfMinus1Retry', but checks for operations that would block. -- throwErrnoIfMinus1RetryMayBlock :: Num a => String -> IO a -> IO b -> IO a throwErrnoIfMinus1RetryMayBlock = throwErrnoIfRetryMayBlock (== -1) --- as `throwErrnoIfMinus1RetryMayBlock', but discards the result +-- | as 'throwErrnoIfMinus1RetryMayBlock', but discards the result. -- throwErrnoIfMinus1RetryMayBlock_ :: Num a => String -> IO a -> IO b -> IO () throwErrnoIfMinus1RetryMayBlock_ = throwErrnoIfRetryMayBlock_ (== -1) --- throws "errno" if a result of a NULL pointer is returned +-- | Throw an 'IOError' corresponding to the current value of 'getErrno' +-- if the 'IO' action returns 'nullPtr'. -- throwErrnoIfNull :: String -> IO (Ptr a) -> IO (Ptr a) throwErrnoIfNull = throwErrnoIf (== nullPtr) --- throws "errno" if a result of a NULL pointer is returned, but retries in --- case of an interrupted operation +-- | Throw an 'IOError' corresponding to the current value of 'getErrno' +-- if the 'IO' action returns 'nullPtr', +-- but retry in case of an interrupted operation. -- throwErrnoIfNullRetry :: String -> IO (Ptr a) -> IO (Ptr a) throwErrnoIfNullRetry = throwErrnoIfRetry (== nullPtr) --- as throwErrnoIfNullRetry, but checks for operations that would block +-- | as 'throwErrnoIfNullRetry', but checks for operations that would block. -- throwErrnoIfNullRetryMayBlock :: String -> IO (Ptr a) -> IO b -> IO (Ptr a) throwErrnoIfNullRetryMayBlock = throwErrnoIfRetryMayBlock (== nullPtr) @@ -399,14 +447,19 @@ throwErrnoIfNullRetryMayBlock = throwErrnoIfRetryMayBlock (== nullPtr) -- conversion of an "errno" value into IO error -- -------------------------------------------- --- convert a location string, an "errno" value, an optional handle, --- and an optional filename into a matching IO error +-- | Construct a Haskell 98 I\/O error based on the given 'Errno' value. +-- The optional information can be used to improve the accuracy of +-- error messages. -- -errnoToIOError :: String -> Errno -> Maybe Handle -> Maybe String -> IOError +errnoToIOError :: String -- ^ the location where the error occurred + -> Errno -- ^ the error number + -> Maybe Handle -- ^ optional handle associated with the error + -> Maybe String -- ^ optional filename associated with the error + -> IOError errnoToIOError loc errno maybeHdl maybeName = unsafePerformIO $ do str <- strerror errno >>= peekCString #if __GLASGOW_HASKELL__ - return (IOException (IOError maybeHdl errType loc str maybeName)) + return (IOError maybeHdl errType loc str maybeName) where errType | errno == eOK = OtherError