From: simonmar Date: Tue, 6 Jan 2004 12:40:01 +0000 (+0000) Subject: [project @ 2004-01-06 12:40:00 by simonmar] X-Git-Tag: nhc98-1-18-release~413 X-Git-Url: http://git.megacz.com/?p=haskell-directory.git;a=commitdiff_plain;h=c5b1770b352e3098de3a88fbb94aa55785b49ed5 [project @ 2004-01-06 12:40:00 by simonmar] Fix, and simplify, the getting/setting of errno in Foreign.C.Error. It was previously wrong: although we called a C function to get the location of errno (correct), we cached the result in a CAF which was wrong because the location is OS thread dependent. We must call the C function every time we need the value of errno. I also simplified things by making the getter/setter functions inlined in the same way as the other C fragments in this library, and putting them in HsBase.h. MERGE TO STABLE --- diff --git a/Foreign/C/Error.hs b/Foreign/C/Error.hs index db17f5f..9b7059d 100644 --- a/Foreign/C/Error.hs +++ b/Foreign/C/Error.hs @@ -123,16 +123,6 @@ import System.IO.Unsafe ( unsafePerformIO ) -- "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 @@ -282,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 :: IO (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 -- --------------------------- diff --git a/cbits/errno.c b/cbits/errno.c deleted file mode 100644 index 04eae07..0000000 --- a/cbits/errno.c +++ /dev/null @@ -1,16 +0,0 @@ -/* - * (c) The University of Glasgow, 2000-2001 - * - * $Id: errno.c,v 1.5 2002/09/25 15:24:07 simonmar Exp $ - * - * GHC Error Number Conversion - */ - -#include "HsBase.h" - -/* Raw errno */ -/* Covers up the fact that on Windows this is a function */ - -int *ghcErrno(void) { - return &errno; -} diff --git a/include/HsBase.h b/include/HsBase.h index 71fd475..9db6133 100644 --- a/include/HsBase.h +++ b/include/HsBase.h @@ -114,9 +114,6 @@ #include "timeUtils.h" #endif -/* in ghc_errno.c */ -int *ghcErrno(void); - /* in system.c */ HsInt systemCmd(HsAddr cmd); @@ -206,6 +203,9 @@ StgWord64 stg_integerToWord64 (StgInt sa, StgByteArray /* Really: mp_limb_t* */ # endif #endif +INLINE int __hscore_get_errno(void) { return errno; } +INLINE int __hscore_set_errno(int e) { errno = e; } + #if !defined(_MSC_VER) INLINE int __hscore_s_isreg(m) { return S_ISREG(m); } INLINE int __hscore_s_isdir(m) { return S_ISDIR(m); } diff --git a/include/ghc_errno.h b/include/ghc_errno.h deleted file mode 100644 index 33b5dce..0000000 --- a/include/ghc_errno.h +++ /dev/null @@ -1,15 +0,0 @@ -/* ----------------------------------------------------------------------------- - * $Id: ghc_errno.h,v 1.1 2001/06/28 14:15:04 simonmar Exp $ - * - * (c) The GHC Team 2001 - * - * Haskell-usable version of errno - * - * ---------------------------------------------------------------------------*/ - -#ifndef GHCERRNO_H -#define GHCERRNO_H - -int *ghcErrno(void); - -#endif