/* ltdl.c -- system independent dlopen wrapper
Copyright (C) 1998, 1999, 2000, 2004, 2005, 2006,
- 2007, 2008 Free Software Foundation, Inc.
+ 2007, 2008, 2011 Free Software Foundation, Inc.
Written by Thomas Tanner, 1998
NOTE: The canonical source of this file is maintained with the
#if defined(LT_MODULE_EXT)
static const char shlib_ext[] = LT_MODULE_EXT;
#endif
+/* If the loadable module suffix is not the same as the linkable
+ * shared library suffix, this will be defined. */
+#if defined(LT_SHARED_EXT)
+static const char shared_ext[] = LT_SHARED_EXT;
+#endif
#if defined(LT_DLSEARCH_PATH)
static const char sys_dlsearch_path[] = LT_DLSEARCH_PATH;
#endif
if (ext && ((streq (ext, archive_ext))
#if defined(LT_MODULE_EXT)
|| (streq (ext, shlib_ext))
+#endif
+#if defined(LT_SHARED_EXT)
+ || (streq (ext, shared_ext))
#endif
))
{
if (handle || ((errors > 0) && !file_not_found ()))
return handle;
#endif
+
+#if defined(LT_SHARED_EXT)
+ /* Try appending SHARED_EXT. */
+ LT__SETERRORSTR (saved_error);
+ errors = try_dlopen (&handle, filename, shared_ext, advise);
+
+ /* As before, if the file was found but loading failed, return now
+ with the current error message. */
+ if (handle || ((errors > 0) && !file_not_found ()))
+ return handle;
+#endif
}
/* Still here? Then we really did fail to locate any of the file
LT_AT_CONFIGURE([LDFLAGS=-L/there/is/no/dir/here])
AT_CHECK([./libtool --config],[ignore],[expout],[ignore])
AT_CLEANUP
+
+AT_SETUP([darwin can lt_dlopen .dylib and .so files])
+
+AT_KEYWORDS([libltdl dylib])
+
+# This test requires shared library support.
+AT_CHECK([$LIBTOOL --features | grep 'enable shared libraries' || exit 77],
+ [], [ignore])
+
+eval `$LIBTOOL --config | $EGREP '^shrext_cmds='`
+
+module=no
+eval shared_ext=\"$shrext_cmds\"
+module=yes
+eval module_ext=\"$shrext_cmds\"
+
+# Only bother with this test if module extension is different from
+# shared extension
+AT_CHECK([test "$shared_ext" != "$module_ext" || exit 77])
+
+# Skip this test when called from:
+# make distcheck DISTCHECK_CONFIGURE_FLAGS=--disable-ltdl-install
+AT_CHECK([case $LIBLTDL in #(
+ */_inst/lib/*) test -f $LIBLTDL || (exit 77) ;;
+esac], [], [ignore])
+
+prefix=`pwd`/inst
+libdir=$prefix/lib
+bindir=$prefix/bin
+mkdir $prefix $libdir $bindir
+
+# This code is copied from the Autobook:
+# <http://sources.redhat.com/autobook/autobook/autobook_169.html>
+# so if it needs changes, be sure to notify the Autobook authors
+# about them.
+
+AT_DATA([simple-module.c],
+[[
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C"
+#endif
+int
+run (const char *argument)
+{
+ printf ("Hello, %s!\n", argument);
+ return 0;
+}
+]])
+
+AT_DATA([ltdl-loader.c],
+[[
+#include <stdio.h>
+#include <stdlib.h>
+#ifndef EXIT_FAILURE
+# define EXIT_FAILURE 1
+# define EXIT_SUCCESS 0
+#endif
+
+#include <limits.h>
+#ifndef PATH_MAX
+# define PATH_MAX 255
+#endif
+
+#include <string.h>
+#include <ltdl.h>
+
+#ifndef MODULE_PATH_ENV
+# define MODULE_PATH_ENV "MODULE_PATH"
+#endif
+
+typedef int entrypoint (const char *argument);
+
+/* Save and return a copy of the dlerror() error message,
+ since the next API call may overwrite the original. */
+static char *dlerrordup (char *errormsg);
+
+int
+main (int argc, const char *argv[])
+{
+ char *errormsg = NULL;
+ lt_dlhandle module = NULL;
+ entrypoint *run = NULL;
+ int errors = 0;
+
+ if (argc != 3)
+ {
+ fprintf (stderr, "USAGE: main MODULENAME ARGUMENT\n");
+ exit (EXIT_FAILURE);
+ }
+
+ /* Initialise libltdl. */
+ errors = lt_dlinit ();
+
+ /* Set the module search path. */
+ if (!errors)
+ {
+ const char *path = getenv (MODULE_PATH_ENV);
+
+ if (path != NULL)
+ errors = lt_dlsetsearchpath (path);
+ }
+
+ /* Load the module. */
+ if (!errors)
+ module = lt_dlopenext (argv[1]);
+
+ /* Find the entry point. */
+ if (module)
+ {
+ run = (entrypoint *) lt_dlsym (module, "run");
+
+ /* In principle, run might legitimately be NULL, so
+ I don't use run == NULL as an error indicator
+ in general. */
+ errormsg = dlerrordup (errormsg);
+ if (errormsg != NULL)
+ {
+ errors = lt_dlclose (module);
+ module = NULL;
+ }
+ }
+ else
+ errors = 1;
+
+ /* Call the entry point function. */
+ if (!errors)
+ {
+ int result = (*run) (argv[2]);
+ if (result < 0)
+ errormsg = strdup ("module entry point execution failed");
+ else
+ printf ("\t=> %d\n", result);
+ }
+
+ /* Unload the module, now that we are done with it. */
+ if (!errors)
+ errors = lt_dlclose (module);
+
+ if (errors)
+ {
+ /* Diagnose the encountered error. */
+ errormsg = dlerrordup (errormsg);
+
+ if (!errormsg)
+ {
+ fprintf (stderr, "%s: dlerror() failed.\n", argv[0]);
+ return EXIT_FAILURE;
+ }
+ }
+
+ /* Finished with ltdl now. */
+ if (!errors)
+ if (lt_dlexit () != 0)
+ errormsg = dlerrordup (errormsg);
+
+ if (errormsg)
+ {
+ fprintf (stderr, "%s: %s.\n", argv[0], errormsg);
+ free (errormsg);
+ exit (EXIT_FAILURE);
+ }
+
+ return EXIT_SUCCESS;
+}
+
+/* Be careful to save a copy of the error message,
+ since the next API call may overwrite the original. */
+static char *
+dlerrordup (char *errormsg)
+{
+ char *error = (char *) lt_dlerror ();
+ if (error && !errormsg)
+ errormsg = strdup (error);
+ return errormsg;
+}
+]])
+
+: ${LTDLINCL="-I$abs_top_srcdir/libltdl"}
+: ${LIBLTDL="$abs_builddir/../libltdl/libltdlc.la"}
+
+CPPFLAGS="$LTDLINCL $CPPFLAGS"
+LDFLAGS="$LDFLAGS -no-undefined"
+
+AT_CHECK([$LIBTOOL --mode=compile $CC $CPPFLAGS $CFLAGS -c simple-module.c],
+ [], [ignore], [ignore])
+AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o simple-module.la ]dnl
+ [simple-module.lo -rpath $libdir -module -avoid-version],
+ [], [ignore], [ignore])
+AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o libsimple-dylib.la ]dnl
+ [simple-module.lo -rpath $libdir -avoid-version],
+ [], [ignore], [ignore])
+AT_CHECK([$CC $CPPFLAGS $CFLAGS -c ltdl-loader.c],
+ [], [ignore], [ignore])
+AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o ltdl-loader$EXEEXT ]dnl
+ [ltdl-loader.$OBJEXT -dlopen self $LIBLTDL],
+ [], [ignore], [ignore])
+AT_CHECK([$LIBTOOL --mode=install cp simple-module.la $libdir/simple-module.la], [], [ignore], [ignore])
+AT_CHECK([$LIBTOOL --mode=install cp libsimple-dylib.la $libdir/libsimple-dylib.la], [], [ignore], [ignore])
+AT_CHECK([$LIBTOOL --mode=clean rm -f simple-module.la], [], [ignore], [ignore])
+AT_CHECK([$LIBTOOL --mode=clean rm -f libsimple-dylib.la], [], [ignore], [ignore])
+
+rm $libdir/simple-module.la
+rm $libdir/libsimple-dylib.la
+
+for dir in inst/lib "$libdir"; do
+ LT_AT_EXEC_CHECK([./ltdl-loader], [], [stdout], [ignore],
+ [$dir/simple-module World])
+ AT_CHECK([grep "Hello, World" stdout], [], [ignore])
+ LT_AT_EXEC_CHECK([./ltdl-loader], [], [stdout], [ignore],
+ [$dir/libsimple-dylib World])
+ AT_CHECK([grep "Hello, World" stdout], [], [ignore])
+done
+
+AT_CLEANUP