diff options
-rw-r--r-- | System/Posix/DynamicLinker/Prim.hsc | 37 | ||||
-rw-r--r-- | configure.ac | 5 |
2 files changed, 27 insertions, 15 deletions
diff --git a/System/Posix/DynamicLinker/Prim.hsc b/System/Posix/DynamicLinker/Prim.hsc index a111e3a..2fe67b4 100644 --- a/System/Posix/DynamicLinker/Prim.hsc +++ b/System/Posix/DynamicLinker/Prim.hsc @@ -41,25 +41,25 @@ import Foreign.Ptr ( Ptr, FunPtr, nullPtr ) import Foreign.C.Types import Foreign.C.String ( CString ) --- RTLD_NEXT madness --- On some host (e.g. SuSe Linux 7.2) RTLD_NEXT is not visible --- without setting _GNU_SOURCE. Since we don't want to set this --- flag, here's a different solution: You can use the Haskell --- function 'haveRtldNext' to check wether the flag is available --- to you. Ideally, this will be optimized by the compiler so --- that it should be as efficient as an #ifdef. --- If you fail to test the flag and use it although it is --- undefined, 'packOneModuleFlag' will bomb. --- The same applies to RTLD_LOCAL which isn't available on + +-- |On some hosts (e.g. SuSe and Ubuntu Linux) 'RTLD_NEXT' (and +-- 'RTLD_DEFAULT') are not visible without setting the macro +-- '_GNU_SOURCE'. Since we don't want to define this macro, you can use +-- the function 'haveRtldNext' to check wether the flag `Next` is +-- available. Ideally, this will be optimized by the compiler so that it +-- should be as efficient as an #ifdef. +-- +-- If you fail to test the flag and use it although it is undefined, +-- 'packDL' will throw an error. +-- +-- The same applies to RTLD_LOCAL which isn't available on -- cygwin. haveRtldNext :: Bool #ifdef HAVE_RTLDNEXT haveRtldNext = True - foreign import ccall unsafe "__hsunix_rtldNext" rtldNext :: Ptr a - #else /* HAVE_RTLDNEXT */ haveRtldNext = False #endif /* HAVE_RTLDNEXT */ @@ -76,6 +76,9 @@ haveRtldLocal = True haveRtldLocal = False #endif /* HAVE_RTLDLOCAL */ + +-- |Flags for 'System.Posix.DynamicLinker.dlopen'. + data RTLDFlags = RTLD_LAZY | RTLD_NOW @@ -112,21 +115,29 @@ packRTLDFlag RTLD_LOCAL = #const RTLD_LOCAL packRTLDFlag RTLD_LOCAL = error "RTLD_LOCAL not available" #endif /* HAVE_RTLDLOCAL */ + -- |Flags for 'System.Posix.DynamicLinker.dlsym'. Notice that 'Next' --- might not be available on your particular platform! +-- might not be available on your particular platform! Use +-- `haveRtldNext`. +-- +-- If 'RTLD_DEFAULT' is not defined on your platform, `packDL` `Default` +-- reduces to 'nullPtr'. data DL = Null | Next | Default | DLHandle (Ptr ()) deriving (Show) packDL :: DL -> Ptr () packDL Null = nullPtr + #ifdef HAVE_RTLDNEXT packDL Next = rtldNext #else packDL Next = error "RTLD_NEXT not available" #endif + #ifdef HAVE_RTLDDEFAULT packDL Default = rtldDefault #else packDL Default = nullPtr #endif + packDL (DLHandle h) = h diff --git a/configure.ac b/configure.ac index f295061..57b7cf7 100644 --- a/configure.ac +++ b/configure.ac @@ -124,7 +124,9 @@ case "$fptools_cv_func_unsetenv_return_type" in ;; esac -dnl ** sometimes RTLD_NEXT is hidden in #ifdefs we really don't wan to set +dnl On some hosts (e.g. SuSe and Ubuntu Linux) RTLD_NEXT and RTLD_DEFAULT are +dnl not visible without setting _GNU_SOURCE, which we really don't want to. +dnl Also see comments in System/Posix/DynamicLinker/Prim.hsc. AC_MSG_CHECKING(for RTLD_NEXT from dlfcn.h) AC_EGREP_CPP(yes, [ @@ -139,7 +141,6 @@ AC_EGREP_CPP(yes, AC_MSG_RESULT(no) ]) -dnl ** RTLD_DEFAULT isn't available on cygwin AC_MSG_CHECKING(for RTLD_DEFAULT from dlfcn.h) AC_EGREP_CPP(yes, [ |