mirror of
git://git.savannah.gnu.org/libtool.git
synced 2024-11-21 01:40:57 +08:00
cec246760f
* tests/dlloader-api.at (dlloader API): Use uglified names for pseudo-modules. Signed-off-by: Charles Wilson <libtool@cwilson.fastmail.fm>
442 lines
10 KiB
Plaintext
442 lines
10 KiB
Plaintext
# 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 <ltdl.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
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 const char *first_module = "first";
|
|
const char *ctx = (const char *) data;
|
|
|
|
/* Use a magic string to avoid possible interactions with filesystem
|
|
* objects. Prepend '/' to short-circuit libltdl's search of
|
|
* $shlibpath_var (e.g. PATH, LD_LIBRARY_PATH, or similar).
|
|
*/
|
|
if (!filename || strcmp (filename, "/libltdl_dlloader_api_test_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 (void *) 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 const char *last_module = "last";
|
|
const char *ctx = (const char *) data;
|
|
|
|
/* Use a magic string to avoid possible interactions with filesystem
|
|
* objects. Prepend '/' to short-circuit libltdl's search of
|
|
* $shlibpath_var (e.g. PATH, LD_LIBRARY_PATH, or similar).
|
|
*/
|
|
if (!filename || strcmp (filename, "/libltdl_dlloader_api_test_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 (void *) 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_dlhandle module = NULL;
|
|
module_func *symbol;
|
|
const char *first_ctx = "first_ctx";
|
|
const char *last_ctx = "last_ctx";
|
|
const lt_dlvtable *finder;
|
|
|
|
LTDL_SET_PRELOADED_SYMBOLS ();
|
|
|
|
if (lt_dlinit ())
|
|
{
|
|
printf ("lt_dlinit failed\n");
|
|
return 1;
|
|
}
|
|
|
|
first = (lt_dlvtable *) 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 = (lt_user_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 = (lt_dlvtable *) 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 = (lt_user_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);
|
|
|
|
/* Use a magic string to avoid possible interactions with filesystem
|
|
* objects. Prepend '/' to short-circuit libltdl's search of
|
|
* $shlibpath_var (e.g. PATH, LD_LIBRARY_PATH, or similar).
|
|
*/
|
|
module = lt_dlopen ("/libltdl_dlloader_api_test_first");
|
|
|
|
if (!module)
|
|
{
|
|
printf ("lt_dlopen failed: %s\n", lt_dlerror ());
|
|
err = 1;
|
|
goto cleanup;
|
|
}
|
|
|
|
symbol = (module_func *) 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 = (module_func *) 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);
|
|
|
|
/* Use a magic string to avoid possible interactions with filesystem
|
|
* objects. Prepend '/' to short-circuit libltdl's search of
|
|
* $shlibpath_var (e.g. PATH, LD_LIBRARY_PATH, or similar).
|
|
*/
|
|
module = lt_dlopen ("/libltdl_dlloader_api_test_last");
|
|
|
|
if (!module)
|
|
{
|
|
printf ("lt_dlopen failed: %s\n", lt_dlerror ());
|
|
err = 1;
|
|
goto cleanup;
|
|
}
|
|
|
|
symbol = (module_func *) 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],
|
|
[[
|
|
#ifdef __cplusplus
|
|
extern "C"
|
|
#endif
|
|
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 ("/libltdl_dlloader_api_test_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 ("/libltdl_dlloader_api_test_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"}
|
|
|
|
# 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])
|
|
|
|
CPPFLAGS="$LTDLINCL $CPPFLAGS"
|
|
|
|
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])
|
|
|
|
dnl Not possible to override the preopen loader, so skip if not shared.
|
|
. ./module.la
|
|
AT_CHECK([test -n "$dlname" || (exit 77)])
|
|
|
|
AT_CHECK([$CC $CPPFLAGS $CFLAGS -c main.c], [], [ignore], [ignore])
|
|
AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o main$EXEEXT ]dnl
|
|
[main.$OBJEXT -dlopen module.la $LIBLTDL],
|
|
[], [ignore], [ignore])
|
|
|
|
LT_AT_EXEC_CHECK([./main], [], [expout], [ignore], [])
|
|
|
|
AT_CLEANUP
|