Commit c566040b authored by bos's avatar bos
Browse files

Merge pull request #2 from thomie/T8902

Add haddock comments on RTLD_NEXT and RTLD_DEFAULT
parents 54fbbdec 5e725064
......@@ -41,25 +41,22 @@ 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
-- cygwin.
-- |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.
haveRtldNext :: Bool
#ifdef HAVE_RTLDNEXT
haveRtldNext = True
foreign import ccall unsafe "__hsunix_rtldNext" rtldNext :: Ptr a
#else /* HAVE_RTLDNEXT */
haveRtldNext = False
#endif /* HAVE_RTLDNEXT */
......@@ -69,12 +66,11 @@ foreign import ccall unsafe "__hsunix_rtldDefault" rtldDefault :: Ptr a
#endif /* HAVE_RTLDDEFAULT */
haveRtldLocal :: Bool
#ifdef HAVE_RTLDLOCAL
haveRtldLocal = True
#else /* HAVE_RTLDLOCAL */
haveRtldLocal = False
#endif /* HAVE_RTLDLOCAL */
{-# DEPRECATED haveRtldLocal "defaults to True" #-}
-- |Flags for 'System.Posix.DynamicLinker.dlopen'.
data RTLDFlags
= RTLD_LAZY
......@@ -93,40 +89,33 @@ packRTLDFlags flags = foldl (\ s f -> (packRTLDFlag f) .|. s) 0 flags
packRTLDFlag :: RTLDFlags -> CInt
packRTLDFlag RTLD_LAZY = #const RTLD_LAZY
#ifdef HAVE_RTLDNOW
packRTLDFlag RTLD_NOW = #const RTLD_NOW
#else /* HAVE_RTLDNOW */
packRTLDFlag RTLD_NOW = error "RTLD_NOW not available"
#endif /* HAVE_RTLDNOW */
#ifdef HAVE_RTLDGLOBAL
packRTLDFlag RTLD_GLOBAL = #const RTLD_GLOBAL
#else /* HAVE_RTLDGLOBAL */
packRTLDFlag RTLD_GLOBAL = error "RTLD_GLOBAL not available"
#endif
#ifdef HAVE_RTLDLOCAL
packRTLDFlag RTLD_LOCAL = #const RTLD_LOCAL
#else /* HAVE_RTLDLOCAL */
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
......@@ -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,
[
......@@ -154,51 +155,6 @@ AC_EGREP_CPP(yes,
AC_MSG_RESULT(no)
])
dnl ** RTLD_LOCAL isn't available on cygwin or openbsd
AC_MSG_CHECKING(for RTLD_LOCAL from dlfcn.h)
AC_EGREP_CPP(yes,
[
#include <dlfcn.h>
#ifdef RTLD_LOCAL
yes
#endif
], [
AC_MSG_RESULT(yes)
AC_DEFINE([HAVE_RTLDLOCAL], [1], [Define to 1 if RTLD_LOCAL is available.])
], [
AC_MSG_RESULT(no)
])
dnl ** RTLD_GLOBAL isn't available on openbsd
AC_MSG_CHECKING(for RTLD_GLOBAL from dlfcn.h)
AC_EGREP_CPP(yes,
[
#include <dlfcn.h>
#ifdef RTLD_GLOBAL
yes
#endif
], [
AC_MSG_RESULT(yes)
AC_DEFINE([HAVE_RTLDGLOBAL], [1], [Define to 1 if RTLD_GLOBAL is available.])
], [
AC_MSG_RESULT(no)
])
dnl ** RTLD_NOW isn't available on openbsd
AC_MSG_CHECKING(for RTLD_NOW from dlfcn.h)
AC_EGREP_CPP(yes,
[
#include <dlfcn.h>
#ifdef RTLD_NOW
yes
#endif
], [
AC_MSG_RESULT(yes)
AC_DEFINE([HAVE_RTLDNOW], [1], [Define to 1 if we can see RTLD_NOW in dlfcn.h])
], [
AC_MSG_RESULT(no)
])
AC_CHECK_FUNCS(openpty,,
AC_CHECK_LIB(util,openpty,
[AC_DEFINE(HAVE_OPENPTY) EXTRA_LIBS="$EXTRA_LIBS util"],
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment