[project @ 2004-01-14 11:16:10 by malcolm]
[haskell-directory.git] / Foreign / C / Error.hs
index 069367b..d7da52d 100644 (file)
@@ -9,7 +9,7 @@
 -- Stability   :  provisional
 -- Portability :  portable
 --
--- C-specific Marshalling support: Handling of C "errno" error codes
+-- C-specific Marshalling support: Handling of C \"errno\" error codes
 --
 -----------------------------------------------------------------------------
 
@@ -79,7 +79,7 @@ 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
 --
 #ifndef __NHC__
@@ -107,7 +107,6 @@ import Foreign.Marshal.Error        ( void )
 import Data.Maybe
 
 #if __GLASGOW_HASKELL__
-import GHC.Storable
 import GHC.IOBase
 import GHC.Num
 import GHC.Base
@@ -116,19 +115,14 @@ import System.IO          ( IOError, Handle, ioError )
 import System.IO.Unsafe                ( unsafePerformIO )
 #endif
 
+#ifdef __HUGS__
+{-# 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]
-#ifdef __NHC__
-foreign import ccall unsafe "errno.h &errno" _errno :: Ptr CInt
-#else
-foreign import ccall unsafe "HsBase.h ghcErrno" _errno :: Ptr CInt
-#endif
-
 -- Haskell representation for "errno" values
 --
 newtype Errno = Errno CInt
@@ -162,104 +156,104 @@ eOK             = Errno 0
 #ifdef __NHC__
 #include "Errno.hs"
 #else
-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)
+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
 
 -- checks whether the given errno value is supported on the current
@@ -278,13 +272,29 @@ isValidErrno (Errno errno)  = errno /= -1
 -- yield the current thread's "errno" value
 --
 getErrno :: IO Errno
-getErrno  = do e <- peek _errno; return (Errno e)
+
+-- 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
 
 -- set the current thread's "errno" value to 0
 --
 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
 -- ---------------------------