content: -----------------------------------------------------------------------------
  -- |
  -- Module      :  GHC.Internal.Foreign.C.Error
  -- Copyright   :  (c) The FFI task force 2001
  -- License     :  BSD-style (see the file libraries/base/LICENSE)
  --
  -- Maintainer  :  ffi@haskell.org
  -- Stability   :  provisional
  -- Portability :  portable
  --
  -- C-specific Marshalling support: Handling of C \"errno\" error codes.
  --
  -----------------------------------------------------------------------------
  
  module Foreign.C.Error (
    -- * Haskell representations of @errno@ values
  
    Errno(..),
  
    eOK, e2BIG, eACCES, eAGAIN, eINTR, eINVAL, eNOENT, ePERM, eRANGE, eROFS, eTXTBSY, eWOULDBLOCK,
  {-
    -- ** 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,
    eEXIST, eFAULT, eFBIG, eFTYPE, eHOSTDOWN, eHOSTUNREACH, eIDRM, eILSEQ,
    eINPROGRESS, eINTR, eINVAL, eIO, eISCONN, eISDIR, eLOOP, eMFILE, eMLINK,
    eMSGSIZE, eMULTIHOP, eNAMETOOLONG, eNETDOWN, eNETRESET, eNETUNREACH,
    eNFILE, eNOBUFS, eNODATA, eNODEV, eNOENT, eNOEXEC, eNOLCK, eNOLINK,
    eNOMEM, eNOMSG, eNONET, eNOPROTOOPT, eNOSPC, eNOSR, eNOSTR, eNOSYS,
    eNOTBLK, eNOTCONN, eNOTDIR, eNOTEMPTY, eNOTSOCK, eNOTSUP, eNOTTY, eNXIO,
    eOPNOTSUPP, ePERM, ePFNOSUPPORT, ePIPE, ePROCLIM, ePROCUNAVAIL,
    ePROGMISMATCH, ePROGUNAVAIL, ePROTO, ePROTONOSUPPORT, ePROTOTYPE,
    eRANGE, eREMCHG, eREMOTE, eROFS, eRPCMISMATCH, eRREMOTE, eSHUTDOWN,
    eSOCKTNOSUPPORT, eSPIPE, eSRCH, eSRMNT, eSTALE, eTIME, eTIMEDOUT,
    eTOOMANYREFS, eTXTBSY, eUSERS, eWOULDBLOCK, eXDEV,
  -}
    -- ** 'Errno' functions
    isValidErrno,
  
    -- access to the current thread's "errno" value
    --
    getErrno,
    resetErrno,
  
    -- conversion of an "errno" value into IO error
    --
    errnoToIOError,
  
    -- throw current "errno" value
    --
    throwErrno,
  
    -- ** Guards for IO operations that may fail
  
    throwErrnoIf,
    throwErrnoIf_,
    throwErrnoIfRetry,
    throwErrnoIfRetry_,
    throwErrnoIfMinus1,
    throwErrnoIfMinus1_,
    throwErrnoIfMinus1Retry,
    throwErrnoIfMinus1Retry_,
    throwErrnoIfNull,
    throwErrnoIfNullRetry,
  
    throwErrnoIfRetryMayBlock,
    throwErrnoIfRetryMayBlock_,
    throwErrnoIfMinus1RetryMayBlock,
    throwErrnoIfMinus1RetryMayBlock_,
    throwErrnoIfNullRetryMayBlock,
  
    throwErrnoPath,
    throwErrnoPathIf,
    throwErrnoPathIf_,
    throwErrnoPathIfNull,
    throwErrnoPathIfMinus1,
    throwErrnoPathIfMinus1_,
  ) where
  import qualified Prelude(); import MiniPrelude
  
  import Foreign.Ptr
  import Foreign.Marshal.Alloc
  import Foreign.C.Types
  import Foreign.C.String
  import Foreign.Storable
  import Data.Functor(void)
  import Data.Maybe
  import System.IO.Base(Handle)
  import System.IO.Error
  import System.IO.Unsafe(unsafePerformIO)
  
  {-
  import GHC.Internal.IO
  import GHC.Internal.IO.Exception
  import GHC.Internal.IO.Handle.Types
  import GHC.Internal.Num
  import GHC.Internal.Base
  -}
  
  newtype Errno = Errno Int
  
  instance Eq Errno where
    errno1@(Errno no1) == errno2@(Errno no2)
      | isValidErrno errno1 && isValidErrno errno2 = no1 == no2
      | otherwise                                  = False
  
  {-
  eOK, e2BIG, eACCES, eADDRINUSE, eADDRNOTAVAIL, eADV, eAFNOSUPPORT, eAGAIN,
    eALREADY, eBADF, eBADMSG, eBADRPC, eBUSY, eCHILD, eCOMM, eCONNABORTED,
    eCONNREFUSED, eCONNRESET, eDEADLK, eDESTADDRREQ, eDIRTY, eDOM, eDQUOT,
    eEXIST, eFAULT, eFBIG, eFTYPE, eHOSTDOWN, eHOSTUNREACH, eIDRM, eILSEQ,
    eINPROGRESS, eINTR, eINVAL, eIO, eISCONN, eISDIR, eLOOP, eMFILE, eMLINK,
    eMSGSIZE, eMULTIHOP, eNAMETOOLONG, eNETDOWN, eNETRESET, eNETUNREACH,
    eNFILE, eNOBUFS, eNODATA, eNODEV, eNOENT, eNOEXEC, eNOLCK, eNOLINK,
    eNOMEM, eNOMSG, eNONET, eNOPROTOOPT, eNOSPC, eNOSR, eNOSTR, eNOSYS,
    eNOTBLK, eNOTCONN, eNOTDIR, eNOTEMPTY, eNOTSOCK, eNOTSUP, eNOTTY, eNXIO,
    eOPNOTSUPP, ePERM, ePFNOSUPPORT, ePIPE, ePROCLIM, ePROCUNAVAIL,
    ePROGMISMATCH, ePROGUNAVAIL, ePROTO, ePROTONOSUPPORT, ePROTOTYPE,
    eRANGE, eREMCHG, eREMOTE, eROFS, eRPCMISMATCH, eRREMOTE, eSHUTDOWN,
    eSOCKTNOSUPPORT, eSPIPE, eSRCH, eSRMNT, eSTALE, eTIME, eTIMEDOUT,
    eTOOMANYREFS, eTXTBSY, eUSERS, eWOULDBLOCK, eXDEV                    :: Errno
  
  eOK             = Errno 0
  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)
  eNOTSUP         = Errno (CONST_ENOTSUP)
  -- ^ @since base-4.7.0.0
  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)
  -}
  
  eOK, e2BIG, eAGAIN, eINTR, eINVAL, eWOULDBLOCK :: Errno
  eOK         = Errno 0
  e2BIG       = Errno c2BIG;       foreign import capi "value E2BIG"       c2BIG       :: Int
  eACCES      = Errno cACCES;      foreign import capi "value EACCES"      cACCES      :: Int
  eAGAIN      = Errno cAGAIN;      foreign import capi "value EAGAIN"      cAGAIN      :: Int
  eINTR       = Errno cINTR;       foreign import capi "value EINTR"       cINTR       :: Int
  eINVAL      = Errno cINVAL;      foreign import capi "value EINVAL"      cINVAL      :: Int
  eNOENT      = Errno cNOENT;      foreign import capi "value ENOENT"      cNOENT      :: Int
  ePERM       = Errno cPERM;       foreign import capi "value EPERM"       cPERM       :: Int
  eRANGE      = Errno cRANGE;      foreign import capi "value ERANGE"      cRANGE      :: Int
  eROFS       = Errno cROFS;       foreign import capi "value EROFS"       cROFS       :: Int
  eTXTBSY     = Errno cTXTBSY ;    foreign import capi "value ETXTBSY"     cTXTBSY     :: Int
  eWOULDBLOCK = Errno cWOULDBLOCK; foreign import capi "value EWOULDBLOCK" cWOULDBLOCK :: Int
  
  isValidErrno               :: Errno -> Bool
  isValidErrno (Errno errno)  = errno /= -1
  
  foreign import ccall unsafe "errno.h &errno" c_errno_ptr :: IO (Ptr Int)
  
  getErrno :: IO Errno
  getErrno = do
    p <- c_errno_ptr
    e <- peek p
    return (Errno e)
  
  resetErrno :: IO ()
  resetErrno = do
    p <- c_errno_ptr
    poke p 0
    return ()
  
  throwErrno :: String -> IO a
  throwErrno loc = do
    errno <- getErrno
    ioError (errnoToIOError loc errno Nothing Nothing)
  
  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
  
  throwErrnoIf_   :: (a -> Bool) -> String -> IO a -> IO ()
  throwErrnoIf_ pred loc f  = void $ throwErrnoIf pred loc f
  
  throwErrnoIfRetry            :: (a -> Bool) -> String -> IO a -> IO a
  throwErrnoIfRetry pred loc f  =
    do
      res <- f
      if pred res
        then do
          err <- getErrno
          if err == eINTR
            then throwErrnoIfRetry pred loc f
            else throwErrno loc
        else return res
  
  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
      if pred res
        then do
          err <- getErrno
          if err == eINTR
            then throwErrnoIfRetryMayBlock pred loc f on_block
            else if err == eWOULDBLOCK || err == eAGAIN
                   then do _ <- on_block
                           throwErrnoIfRetryMayBlock pred loc f on_block
                   else throwErrno loc
        else return res
  
  throwErrnoIfRetry_            :: (a -> Bool) -> String -> IO a -> IO ()
  throwErrnoIfRetry_ pred loc f  = void $ throwErrnoIfRetry pred loc f
  
  throwErrnoIfRetryMayBlock_ :: (a -> Bool) -> String -> IO a -> IO b -> IO ()
  throwErrnoIfRetryMayBlock_ pred loc f on_block
    = void $ throwErrnoIfRetryMayBlock pred loc f on_block
  
  throwErrnoIfMinus1 :: (Eq a, Num a) => String -> IO a -> IO a
  throwErrnoIfMinus1  = throwErrnoIf (== (-1))
  
  throwErrnoIfMinus1_ :: (Eq a, Num a) => String -> IO a -> IO ()
  throwErrnoIfMinus1_  = throwErrnoIf_ (== (-1))
  
  throwErrnoIfMinus1Retry :: (Eq a, Num a) => String -> IO a -> IO a
  throwErrnoIfMinus1Retry  = throwErrnoIfRetry (== (-1))
  
  throwErrnoIfMinus1Retry_ :: (Eq a, Num a) => String -> IO a -> IO ()
  throwErrnoIfMinus1Retry_  = throwErrnoIfRetry_ (== (-1))
  
  throwErrnoIfMinus1RetryMayBlock :: (Eq a, Num a)
                                  => String -> IO a -> IO b -> IO a
  throwErrnoIfMinus1RetryMayBlock  = throwErrnoIfRetryMayBlock (== (-1))
  
  throwErrnoIfMinus1RetryMayBlock_ :: (Eq a, Num a)
                                   => String -> IO a -> IO b -> IO ()
  throwErrnoIfMinus1RetryMayBlock_  = throwErrnoIfRetryMayBlock_ (== (-1))
  
  throwErrnoIfNull :: String -> IO (Ptr a) -> IO (Ptr a)
  throwErrnoIfNull  = throwErrnoIf (== nullPtr)
  
  throwErrnoIfNullRetry :: String -> IO (Ptr a) -> IO (Ptr a)
  throwErrnoIfNullRetry  = throwErrnoIfRetry (== nullPtr)
  
  throwErrnoIfNullRetryMayBlock :: String -> IO (Ptr a) -> IO b -> IO (Ptr a)
  throwErrnoIfNullRetryMayBlock  = throwErrnoIfRetryMayBlock (== nullPtr)
  
  throwErrnoPath :: String -> FilePath -> IO a
  throwErrnoPath loc path =
    do
      errno <- getErrno
      ioError (errnoToIOError loc errno Nothing (Just path))
  
  throwErrnoPathIf :: (a -> Bool) -> String -> FilePath -> IO a -> IO a
  throwErrnoPathIf pred loc path f =
    do
      res <- f
      if pred res then throwErrnoPath loc path else return res
  
  throwErrnoPathIf_ :: (a -> Bool) -> String -> FilePath -> IO a -> IO ()
  throwErrnoPathIf_ pred loc path f  = void $ throwErrnoPathIf pred loc path f
  
  throwErrnoPathIfNull :: String -> FilePath -> IO (Ptr a) -> IO (Ptr a)
  throwErrnoPathIfNull  = throwErrnoPathIf (== nullPtr)
  
  throwErrnoPathIfMinus1 :: (Eq a, Num a) => String -> FilePath -> IO a -> IO a
  throwErrnoPathIfMinus1 = throwErrnoPathIf (== (-1))
  
  throwErrnoPathIfMinus1_ :: (Eq a, Num a) => String -> FilePath -> IO a -> IO ()
  throwErrnoPathIfMinus1_  = throwErrnoPathIf_ (== (-1))
  
  
  foreign import ccall "string.h strerror_r"
      c_strerror_r :: Int -> CString -> CSize -> IO Int
  
  errnoToString :: Errno -> IO String
  errnoToString (Errno errno) =
      allocaBytes 512 $ \ ptr -> do
          ret <- c_strerror_r errno ptr (CSize 512)
          if ret /= 0
            then return "errnoToString failed"
            else peekCString ptr
    where len = 512::Int
  
  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@(Errno errno') maybeHdl maybeName = unsafePerformIO $ do
      str <- errnoToString errno
      return (IOError maybeHdl errType loc str (Just errno') maybeName)
    where
      errType
          | errno == eOK             = OtherError
          | errno == e2BIG           = ResourceExhausted
          | errno == eACCES          = PermissionDenied
  {-
          | errno == eADDRINUSE      = ResourceBusy
          | errno == eADDRNOTAVAIL   = UnsupportedOperation
          | errno == eADV            = OtherError
          | errno == eAFNOSUPPORT    = UnsupportedOperation
  -}
          | errno == eAGAIN          = ResourceExhausted
  {-
          | errno == eALREADY        = AlreadyExists
          | errno == eBADF           = InvalidArgument
          | errno == eBADMSG         = InappropriateType
          | errno == eBADRPC         = OtherError
          | errno == eBUSY           = ResourceBusy
          | errno == eCHILD          = NoSuchThing
          | errno == eCOMM           = ResourceVanished
          | errno == eCONNABORTED    = OtherError
          | errno == eCONNREFUSED    = NoSuchThing
          | errno == eCONNRESET      = ResourceVanished
          | errno == eDEADLK         = ResourceBusy
          | errno == eDESTADDRREQ    = InvalidArgument
          | errno == eDIRTY          = UnsatisfiedConstraints
          | errno == eDOM            = InvalidArgument
          | errno == eDQUOT          = PermissionDenied
          | errno == eEXIST          = AlreadyExists
          | errno == eFAULT          = OtherError
          | errno == eFBIG           = PermissionDenied
          | errno == eFTYPE          = InappropriateType
          | errno == eHOSTDOWN       = NoSuchThing
          | errno == eHOSTUNREACH    = NoSuchThing
          | errno == eIDRM           = ResourceVanished
          | errno == eILSEQ          = InvalidArgument
          | errno == eINPROGRESS     = AlreadyExists
  -}
          | errno == eINTR           = Interrupted
          | errno == eINVAL          = InvalidArgument
  {-
          | errno == eIO             = HardwareFault
          | errno == eISCONN         = AlreadyExists
          | errno == eISDIR          = InappropriateType
          | errno == eLOOP           = InvalidArgument
          | errno == eMFILE          = ResourceExhausted
          | errno == eMLINK          = ResourceExhausted
          | errno == eMSGSIZE        = ResourceExhausted
          | errno == eMULTIHOP       = UnsupportedOperation
          | errno == eNAMETOOLONG    = InvalidArgument
          | errno == eNETDOWN        = ResourceVanished
          | errno == eNETRESET       = ResourceVanished
          | errno == eNETUNREACH     = NoSuchThing
          | errno == eNFILE          = ResourceExhausted
          | errno == eNOBUFS         = ResourceExhausted
          | errno == eNODATA         = NoSuchThing
          | errno == eNODEV          = UnsupportedOperation
  -}
          | errno == eNOENT          = NoSuchThing
  {-
          | errno == eNOEXEC         = InvalidArgument
          | errno == eNOLCK          = ResourceExhausted
          | errno == eNOLINK         = ResourceVanished
          | errno == eNOMEM          = ResourceExhausted
          | errno == eNOMSG          = NoSuchThing
          | errno == eNONET          = NoSuchThing
          | errno == eNOPROTOOPT     = UnsupportedOperation
          | errno == eNOSPC          = ResourceExhausted
          | errno == eNOSR           = ResourceExhausted
          | errno == eNOSTR          = InvalidArgument
          | errno == eNOSYS          = UnsupportedOperation
          | errno == eNOTBLK         = InvalidArgument
          | errno == eNOTCONN        = InvalidArgument
          | errno == eNOTDIR         = InappropriateType
          | errno == eNOTEMPTY       = UnsatisfiedConstraints
          | errno == eNOTSOCK        = InvalidArgument
          | errno == eNOTTY          = IllegalOperation
          | errno == eNXIO           = NoSuchThing
          | errno == eOPNOTSUPP      = UnsupportedOperation
  -}
          | errno == ePERM           = PermissionDenied
  {-
          | errno == ePFNOSUPPORT    = UnsupportedOperation
          | errno == ePIPE           = ResourceVanished
          | errno == ePROCLIM        = PermissionDenied
          | errno == ePROCUNAVAIL    = UnsupportedOperation
          | errno == ePROGMISMATCH   = ProtocolError
          | errno == ePROGUNAVAIL    = UnsupportedOperation
          | errno == ePROTO          = ProtocolError
          | errno == ePROTONOSUPPORT = ProtocolError
          | errno == ePROTOTYPE      = ProtocolError
  -}
          | errno == eRANGE          = UnsupportedOperation
  {-
          | errno == eREMCHG         = ResourceVanished
          | errno == eREMOTE         = IllegalOperation
  -}
          | errno == eROFS           = PermissionDenied
  {-
          | errno == eRPCMISMATCH    = ProtocolError
          | errno == eRREMOTE        = IllegalOperation
          | errno == eSHUTDOWN       = IllegalOperation
          | errno == eSOCKTNOSUPPORT = UnsupportedOperation
          | errno == eSPIPE          = UnsupportedOperation
          | errno == eSRCH           = NoSuchThing
          | errno == eSRMNT          = UnsatisfiedConstraints
          | errno == eSTALE          = ResourceVanished
          | errno == eTIME           = TimeExpired
          | errno == eTIMEDOUT       = TimeExpired
          | errno == eTOOMANYREFS    = ResourceExhausted
  -}
          | errno == eTXTBSY         = ResourceBusy
  {-
          | errno == eUSERS          = ResourceExhausted
  -}
          | errno == eWOULDBLOCK     = OtherError
  {-
          | errno == eXDEV           = UnsupportedOperation
  -}
          | otherwise                = OtherError
  
  