content: {-# OPTIONS_JHC -fno-prelude  -fffi #-}
  -----------------------------------------------------------------------------
  -- |
  -- Module      :  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(..),		-- 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,
    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, 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
                          -- :: Errno
    isValidErrno,		-- :: Errno -> Bool
  
    -- access to the current thread's "errno" value
    --
    getErrno,             -- :: IO Errno
    resetErrno,           -- :: IO ()
  
    -- conversion of an "errno" value into IO error
    --
    errnoToIOError,       -- :: String       -- location
                          -- -> Errno        -- errno
                          -- -> Maybe Handle -- handle
                          -- -> Maybe String -- filename
                          -- -> IOError
  
    -- throw current "errno" value
    --
    throwErrno,           -- ::                String               -> IO a
  
    -- ** 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
    throwErrnoIfRetry_,   -- :: (a -> Bool) -> String -> IO a       -> IO ()
    throwErrnoIfMinus1,   -- :: Num a
  			-- =>                String -> IO a       -> IO a
    throwErrnoIfMinus1_,  -- :: Num a
  			-- =>                String -> IO a       -> IO ()
    throwErrnoIfMinus1Retry,
  			-- :: Num a
  			-- =>                String -> IO a       -> IO a
    throwErrnoIfMinus1Retry_,
  			-- :: Num a
  			-- =>                String -> IO a       -> IO ()
    throwErrnoIfNull,	-- ::                String -> IO (Ptr a) -> IO (Ptr a)
    throwErrnoIfNullRetry,-- ::                String -> IO (Ptr a) -> IO (Ptr a)
  
    throwErrnoIfRetryMayBlock,
    throwErrnoIfRetryMayBlock_,
    throwErrnoIfMinus1RetryMayBlock,
    throwErrnoIfMinus1RetryMayBlock_,
    throwErrnoIfNullRetryMayBlock
  ) where
  
  
  import Foreign.C.String
  import Foreign.Ptr
  import Foreign.Storable
  import Jhc.Basics
  import Jhc.Basics
  import Jhc.IO
  import Jhc.Maybe
  import Jhc.Monad
  import Jhc.Num
  import Jhc.Order
  import Jhc.Type.C
  
  
  
  
  instance Eq Errno where
    errno1@(Errno no1) == errno2@(Errno no2)
      | isValidErrno errno1 && isValidErrno errno2 = no1 == no2
      | otherwise					 = False
  
  -- common "errno" symbols
  --
  {-
  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, 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
  -- -}
  -- the cCONST_XXX identifiers are cpp symbols whose value is computed by
  -- configure
  --
  eOK             = Errno 0
  {-
  #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
  --
  -- the configure script sets all invalid "errno"s to -1
  --
  isValidErrno (Errno errno)  = errno /= -1
  
  
  -- access to the current thread's "errno" value
  -- --------------------------------------------
  
  -- | Get the current value of @errno@ in the current thread.
  --
  getErrno :: IO Errno
  
  -- 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.
  getErrno = do e <- peek _errno; return (Errno e)
  foreign import ccall "errno.h &errno" _errno :: Ptr CInt
  
  -- | Reset the current thread\'s @errno@ value to 'eOK'.
  --
  resetErrno :: IO ()
  
  -- Again, setting errno has to be done via a C function.
  resetErrno = poke _errno 0
  
  -- throw current "errno" value
  -- ---------------------------
  
  -- | Throw an 'IOError' corresponding to the current value of 'getErrno'.
  --
  throwErrno     :: String	-- ^ textual description of the error location
  	       -> IO a
  throwErrno loc  =
    do
      errno <- getErrno
      ioError (errnoToIOError loc errno Nothing Nothing)
  
  
  -- guards for IO operations that may fail
  -- --------------------------------------
  
  -- | 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)	-- ^ 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 of the 'IO' action after
  -- error handling.
  --
  throwErrnoIf_   :: (a -> Bool) -> String -> IO a -> IO ()
  throwErrnoIf_ pred loc f  = throwErrnoIf pred loc f >> return ()
  
  -- | 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  =
    do
      res <- f
      if pred res
        then do
  	err <- getErrno
  	if err == eINTR
  	  then throwErrnoIfRetry pred loc f
  	  else throwErrno loc
        else return res
  
  -- | 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
      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
  
  -- | as 'throwErrnoIfRetry', but discards the result.
  --
  throwErrnoIfRetry_            :: (a -> Bool) -> String -> IO a -> IO ()
  throwErrnoIfRetry_ pred loc f  = throwErrnoIfRetry pred loc f >> return ()
  
  -- | as 'throwErrnoIfRetryMayBlock', but discards the result.
  --
  throwErrnoIfRetryMayBlock_ :: (a -> Bool) -> String -> IO a -> IO b -> IO ()
  throwErrnoIfRetryMayBlock_ pred loc f on_block
    = throwErrnoIfRetryMayBlock pred loc f on_block >> return ()
  
  -- | 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.
  --
  throwErrnoIfMinus1_ :: Num a => String -> IO a -> IO ()
  throwErrnoIfMinus1_  = throwErrnoIf_ (== -1)
  
  -- | 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.
  --
  throwErrnoIfMinus1Retry_ :: Num a => String -> IO a -> IO ()
  throwErrnoIfMinus1Retry_  = throwErrnoIfRetry_ (== -1)
  
  -- | 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.
  --
  throwErrnoIfMinus1RetryMayBlock_ :: Num a => String -> IO a -> IO b -> IO ()
  throwErrnoIfMinus1RetryMayBlock_  = throwErrnoIfRetryMayBlock_ (== -1)
  
  -- | 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)
  
  -- | 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.
  --
  throwErrnoIfNullRetryMayBlock :: String -> IO (Ptr a) -> IO b -> IO (Ptr a)
  throwErrnoIfNullRetryMayBlock  = throwErrnoIfRetryMayBlock (== nullPtr)
  
  -- conversion of an "errno" value into 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	-- ^ the location where the error occurred
  		-> Errno	-- ^ the error number
  		-> Maybe a	-- ^ 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 (IOError maybeHdl errType loc str 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           = OtherError
          | 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
  #else
  #endif
  -}
      return (userError (loc ++ ": " ++ str ++ maybe "" (": "++) maybeName))
  -- #endif
  
  foreign import ccall  "string.h strerror" strerror :: Errno -> IO (Ptr CChar)
  foreign import primitive "const.EINTR" eINTR :: Errno
  foreign import primitive "const.EWOULDBLOCK" eWOULDBLOCK :: Errno
  foreign import primitive "const.EAGAIN" eAGAIN :: Errno
  