diff --git a/Makefile.am b/Makefile.am index 40a0138..29a639a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -485,6 +485,7 @@ TESTSUITE_AT = tests/testsuite.at \ tests/lt_dlopen_a.at \ tests/lt_dlopenext.at \ tests/ltdl-api.at \ + tests/dlloader-api.at \ tests/loadlibrary.at \ tests/lalib-syntax.at \ tests/resident.at \ diff --git a/tests/dlloader-api.at b/tests/dlloader-api.at new file mode 100644 index 0000000..25a01a9 --- /dev/null +++ b/tests/dlloader-api.at @@ -0,0 +1,409 @@ +# dlloader.at -- test dlloader functionality -*- Autotest -*- +# +# Copyright (C) 2010 Free Software Foundation, Inc. +# This file is part of GNU Libtool. +# +# GNU Libtool is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# GNU Libtool is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with GNU Libtool; see the file COPYING. If not, a copy +# can be downloaded from http://www.gnu.org/licenses/gpl.html, +# or obtained by writing to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +#### + +AT_SETUP([dlloader API]) +AT_KEYWORDS([libltdl]) + +AT_DATA([main.c], +[[#include +#include +#include +#include + +static int +first_init (lt_user_data data) +{ + const char *ctx = (const char *)data; + + printf ("first_init: %s\n", ctx); + + return 0; +} + +static lt_module +first_open (lt_user_data data, const char *filename, lt_dladvise advise) +{ + static char *first_module = "first"; + const char *ctx = (const char *)data; + + if (!filename || strcmp (filename, "first")) + { + printf ("first_open denies a request\n"); + lt_dlseterror (LT_ERROR_FILE_NOT_FOUND); + return NULL; + } + + printf ("first_open (\"%s\"): %s\n", filename, ctx); + + return (lt_module) first_module; +} + +static const char * +first_symbol (void) +{ + return "first_symbol"; +} + +static void * +first_sym (lt_user_data data, lt_module module, const char *symbolname) +{ + const char *ctx = (const char *)data; + const char *filename = (const char *)module; + + printf ("first_sym (%s): %s\n", filename, ctx); + + return first_symbol; +} + +static int +first_close (lt_user_data data, lt_module module) +{ + const char *ctx = (const char *)data; + const char *filename = (const char *)module; + + printf ("first_close (%s): %s\n", filename, ctx); + + return 0; +} + +static int +first_exit (lt_user_data data) +{ + const char *ctx = (const char *)data; + + printf ("first_exit: %s\n", ctx); + + return 0; +} + +static int +last_init (lt_user_data data) +{ + const char *ctx = (const char *)data; + + printf ("last_init: %s\n", ctx); + + return 0; +} + +static lt_module +last_open (lt_user_data data, const char *filename, lt_dladvise advise) +{ + static char *last_module = "last"; + const char *ctx = (const char *)data; + + if (!filename || strcmp (filename, "last")) + { + printf ("last_open denies a request\n"); + lt_dlseterror (LT_ERROR_FILE_NOT_FOUND); + return NULL; + } + + printf ("last_open (\"%s\"): %s\n", filename, ctx); + + return (lt_module) last_module; +} + +static const char * +last_symbol (void) +{ + return "last_symbol"; +} + +static void * +last_sym (lt_user_data data, lt_module module, const char *symbolname) +{ + const char *ctx = (const char *)data; + const char *filename = (const char *)module; + + printf ("last_sym (%s): %s\n", filename, ctx); + + return last_symbol; +} + +static int +last_close (lt_user_data data, lt_module module) +{ + const char *ctx = (const char *)data; + const char *filename = (const char *)module; + + printf ("last_close (%s): %s\n", filename, ctx); + + return 0; +} + +static int +last_exit (lt_user_data data) +{ + const char *ctx = (const char *)data; + + printf ("last_exit: %s\n", ctx); + + return 0; +} + +typedef const char *module_func (void); + +int +main (int argc, char* argv[]) +{ + int err = 0; + lt_dlvtable *first; + lt_dlvtable *last; + lt_module module = NULL; + module_func *symbol; + char *first_ctx = "first_ctx"; + char *last_ctx = "last_ctx"; + const lt_dlvtable *finder; + + if (lt_dlinit ()) + { + printf ("lt_dlinit failed\n"); + return 1; + } + + first = malloc (sizeof (*first)); + if (!first) + { + printf ("malloc failed\n"); + err = 1; + goto cleanup; + } + + first->name = "first"; + first->sym_prefix = NULL; + first->module_open = first_open; + first->module_close = first_close; + first->find_sym = first_sym; + first->dlloader_init = first_init; /* test that it isn't called twice */ + first->dlloader_exit = first_exit; + first->dlloader_data = first_ctx; + first->priority = LT_DLLOADER_PREPEND; + + if (first_init (first->dlloader_data)) + { + printf ("first_init failed\n"); + err = 1; + goto cleanup; + } + + if (lt_dlloader_add (first)) + { + printf ("lt_dlloader_add failed: %s\n", lt_dlerror ()); + err = 1; + goto cleanup; + } + + finder = lt_dlloader_find ("first"); + + if (!finder) + { + printf ("lt_dlloader_find failed: %s\n", lt_dlerror ()); + err = 1; + goto cleanup; + } + + printf ("Found loader \"%s\"\n", finder->name); + + last = malloc (sizeof (*last)); + if (!last) + { + printf ("malloc failed\n"); + err = 1; + goto cleanup; + } + + last->name = "last"; + last->sym_prefix = NULL; + last->module_open = last_open; + last->module_close = last_close; + last->find_sym = last_sym; + last->dlloader_init = last_init; /* test that it isn't called twice */ + last->dlloader_exit = last_exit; + last->dlloader_data = last_ctx; + last->priority = LT_DLLOADER_APPEND; + + if (last_init (last->dlloader_data)) + { + printf ("last_init failed\n"); + err = 1; + goto cleanup; + } + + if (lt_dlloader_add (last)) + { + printf ("lt_dlloader_add failed: %s\n", lt_dlerror ()); + err = 1; + goto cleanup; + } + + finder = lt_dlloader_find ("last"); + + if (!finder) + { + printf ("lt_dlloader_find failed: %s\n", lt_dlerror ()); + err = 1; + goto cleanup; + } + + printf ("Found loader \"%s\"\n", finder->name); + + module = lt_dlopen ("first"); + + if (!module) + { + printf ("lt_dlopen failed: %s\n", lt_dlerror ()); + err = 1; + goto cleanup; + } + + symbol = lt_dlsym (module, "symbol"); + + if (!symbol) + { + printf ("lt_dlsym failed: %s\n", lt_dlerror ()); + err = 1; + goto cleanup; + } + + printf ("result: %s\n", symbol ()); + + lt_dlclose (module); + module = lt_dlopen ("./module.la"); + + if (!module) + { + printf ("lt_dlopen failed: %s\n", lt_dlerror ()); + err = 1; + goto cleanup; + } + + symbol = lt_dlsym (module, "symbol"); + + if (!symbol) + { + printf ("lt_dlsym failed: %s\n", lt_dlerror ()); + err = 1; + goto cleanup; + } + + printf ("result: %s\n", symbol ()); + + lt_dlclose (module); + module = lt_dlopen ("last"); + + if (!module) + { + printf ("lt_dlopen failed: %s\n", lt_dlerror ()); + err = 1; + goto cleanup; + } + + symbol = lt_dlsym (module, "symbol"); + + if (!symbol) + { + printf ("lt_dlsym failed: %s\n", lt_dlerror ()); + err = 1; + goto cleanup; + } + + printf ("result: %s\n", symbol ()); + + if (lt_dlopen ("no-module")) + { + printf ("lt_dlopen unexpectedly opened \"no-module\"\n"); + err = 1; + goto cleanup; + } + + if (lt_dlloader_remove ("first") != first) + { + printf ("vtable of first loader has changed\n"); + err = 1; + goto cleanup; + } + + free (first); + +cleanup: + if (module) + { + lt_dlclose (module); + } + lt_dlexit (); + return err; +} +]]) + +AT_DATA([module.c], +[[ +const char *symbol (void); +const char * +symbol (void) +{ + return "module_symbol"; +} +]]) + +LT_AT_HOST_DATA(expout, +[[first_init: first_ctx +Found loader "first" +last_init: last_ctx +Found loader "last" +first_open ("first"): first_ctx +first_sym (first): first_ctx +result: first_symbol +first_close (first): first_ctx +first_open denies a request +result: module_symbol +first_open denies a request +last_open ("last"): last_ctx +last_sym (last): last_ctx +result: last_symbol +first_open denies a request +last_open denies a request +first_exit: first_ctx +last_close (last): last_ctx +last_exit: last_ctx +]]) + +: ${LTDLINCL="-I$abs_top_srcdir/libltdl"} +: ${LIBLTDL="$abs_builddir/../libltdl/libltdlc.la"} + +CPPFLAGS="$LTDLINCL $CPPFLAGS" + +AT_CHECK([$CC $CPPFLAGS $CFLAGS -c main.c], [], [ignore], [ignore]) +AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o main$EXEEXT ]dnl + [main.$OBJEXT $LIBLTDL], + [], [ignore], [ignore]) + +AT_CHECK([$LIBTOOL --mode=compile $CC $CPPFLAGS $CFLAGS -c module.c], + [], [ignore], [ignore]) +AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o module.la ]dnl + [-rpath /nowhere -module -avoid-version -no-undefined ]dnl + [module.lo], + [], [ignore], [ignore]) + +LT_AT_EXEC_CHECK([./main], [], [expout], [ignore], []) + +AT_CLEANUP