1 # dlloader.at -- test dlloader functionality -*- Autotest -*-
3 # Copyright (C) 2010-2019, 2021-2024 Free Software Foundation, Inc.
4 # This file is part of GNU Libtool.
6 # GNU Libtool is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License as
8 # published by the Free Software Foundation; either version 2 of
9 # the License, or (at your option) any later version.
11 # GNU Libtool is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with GNU Libtool; see the file COPYING. If not, a copy
18 # can be downloaded from http://www.gnu.org/licenses/gpl.html,
19 # or obtained by writing to the Free Software Foundation, Inc.,
20 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 AT_SETUP([dlloader API])
24 AT_KEYWORDS([libltdl])
33 first_init (lt_user_data data)
35 const char *ctx = (const char *) data;
37 printf ("first_init: %s\n", ctx);
43 first_open (lt_user_data data, const char *filename, lt_dladvise advise)
45 static const char *first_module = "first";
46 const char *ctx = (const char *) data;
48 /* Use a magic string to avoid possible interactions with file system
49 * objects. Prepend '/' to short-circuit libltdl's search of
50 * $shlibpath_var (e.g. PATH, LD_LIBRARY_PATH, or similar).
52 if (!filename || strcmp (filename, "/libltdl_dlloader_api_test_first"))
54 printf ("first_open denies a request\n");
55 lt_dlseterror (LT_ERROR_FILE_NOT_FOUND);
59 printf ("first_open (\"%s\"): %s\n", filename, ctx);
61 return (lt_module) first_module;
67 return "first_symbol";
71 first_sym (lt_user_data data, lt_module module, const char *symbolname)
73 const char *ctx = (const char *) data;
74 const char *filename = (const char *) module;
76 printf ("first_sym (%s): %s\n", filename, ctx);
78 return (void *) first_symbol;
82 first_close (lt_user_data data, lt_module module)
84 const char *ctx = (const char *) data;
85 const char *filename = (const char *) module;
87 printf ("first_close (%s): %s\n", filename, ctx);
93 first_exit (lt_user_data data)
95 const char *ctx = (const char *) data;
97 printf ("first_exit: %s\n", ctx);
103 last_init (lt_user_data data)
105 const char *ctx = (const char *) data;
107 printf ("last_init: %s\n", ctx);
113 last_open (lt_user_data data, const char *filename, lt_dladvise advise)
115 static const char *last_module = "last";
116 const char *ctx = (const char *) data;
118 /* Use a magic string to avoid possible interactions with file system
119 * objects. Prepend '/' to short-circuit libltdl's search of
120 * $shlibpath_var (e.g. PATH, LD_LIBRARY_PATH, or similar).
122 if (!filename || strcmp (filename, "/libltdl_dlloader_api_test_last"))
124 printf ("last_open denies a request\n");
125 lt_dlseterror (LT_ERROR_FILE_NOT_FOUND);
129 printf ("last_open (\"%s\"): %s\n", filename, ctx);
131 return (lt_module) last_module;
137 return "last_symbol";
141 last_sym (lt_user_data data, lt_module module, const char *symbolname)
143 const char *ctx = (const char *) data;
144 const char *filename = (const char *) module;
146 printf ("last_sym (%s): %s\n", filename, ctx);
148 return (void *) last_symbol;
152 last_close (lt_user_data data, lt_module module)
154 const char *ctx = (const char *) data;
155 const char *filename = (const char *) module;
157 printf ("last_close (%s): %s\n", filename, ctx);
163 last_exit (lt_user_data data)
165 const char *ctx = (const char *) data;
167 printf ("last_exit: %s\n", ctx);
172 typedef const char *module_func (void);
175 main (int argc, char* argv[])
180 lt_dlhandle module = NULL;
182 const char *first_ctx = "first_ctx";
183 const char *last_ctx = "last_ctx";
184 const lt_dlvtable *finder;
186 LTDL_SET_PRELOADED_SYMBOLS ();
190 printf ("lt_dlinit failed\n");
194 first = (lt_dlvtable *) malloc (sizeof (*first));
197 printf ("malloc failed\n");
202 first->name = "first";
203 first->sym_prefix = NULL;
204 first->module_open = first_open;
205 first->module_close = first_close;
206 first->find_sym = first_sym;
207 first->dlloader_init = first_init; /* test that it isn't called twice */
208 first->dlloader_exit = first_exit;
209 first->dlloader_data = (lt_user_data) first_ctx;
210 first->priority = LT_DLLOADER_PREPEND;
212 if (first_init (first->dlloader_data))
214 printf ("first_init failed\n");
219 if (lt_dlloader_add (first))
221 printf ("lt_dlloader_add failed: %s\n", lt_dlerror ());
226 finder = lt_dlloader_find ("first");
230 printf ("lt_dlloader_find failed: %s\n", lt_dlerror ());
235 printf ("Found loader \"%s\"\n", finder->name);
237 last = (lt_dlvtable *) malloc (sizeof (*last));
240 printf ("malloc failed\n");
246 last->sym_prefix = NULL;
247 last->module_open = last_open;
248 last->module_close = last_close;
249 last->find_sym = last_sym;
250 last->dlloader_init = last_init; /* test that it isn't called twice */
251 last->dlloader_exit = last_exit;
252 last->dlloader_data = (lt_user_data) last_ctx;
253 last->priority = LT_DLLOADER_APPEND;
255 if (last_init (last->dlloader_data))
257 printf ("last_init failed\n");
262 if (lt_dlloader_add (last))
264 printf ("lt_dlloader_add failed: %s\n", lt_dlerror ());
269 finder = lt_dlloader_find ("last");
273 printf ("lt_dlloader_find failed: %s\n", lt_dlerror ());
278 printf ("Found loader \"%s\"\n", finder->name);
280 /* Use a magic string to avoid possible interactions with file system
281 * objects. Prepend '/' to short-circuit libltdl's search of
282 * $shlibpath_var (e.g. PATH, LD_LIBRARY_PATH, or similar).
284 module = lt_dlopen ("/libltdl_dlloader_api_test_first");
288 printf ("lt_dlopen failed: %s\n", lt_dlerror ());
293 symbol = (module_func *) lt_dlsym (module, "symbol");
297 printf ("lt_dlsym failed: %s\n", lt_dlerror ());
302 printf ("result: %s\n", symbol ());
305 module = lt_dlopen ("./module.la");
309 printf ("lt_dlopen failed: %s\n", lt_dlerror ());
314 symbol = (module_func *) lt_dlsym (module, "symbol");
318 printf ("lt_dlsym failed: %s\n", lt_dlerror ());
323 printf ("result: %s\n", symbol ());
327 /* Use a magic string to avoid possible interactions with file system
328 * objects. Prepend '/' to short-circuit libltdl's search of
329 * $shlibpath_var (e.g. PATH, LD_LIBRARY_PATH, or similar).
331 module = lt_dlopen ("/libltdl_dlloader_api_test_last");
335 printf ("lt_dlopen failed: %s\n", lt_dlerror ());
340 symbol = (module_func *) lt_dlsym (module, "symbol");
344 printf ("lt_dlsym failed: %s\n", lt_dlerror ());
349 printf ("result: %s\n", symbol ());
351 if (lt_dlopen ("no-module"))
353 printf ("lt_dlopen unexpectedly opened \"no-module\"\n");
358 if (lt_dlloader_remove ("first") != first)
360 printf ("vtable of first loader has changed\n");
382 const char *symbol (void);
386 return "module_symbol";
390 LT_AT_HOST_DATA(expout,
391 [[first_init: first_ctx
395 first_open ("/libltdl_dlloader_api_test_first"): first_ctx
396 first_sym (first): first_ctx
398 first_close (first): first_ctx
399 first_open denies a request
400 result: module_symbol
401 first_open denies a request
402 last_open ("/libltdl_dlloader_api_test_last"): last_ctx
403 last_sym (last): last_ctx
405 first_open denies a request
406 last_open denies a request
407 first_exit: first_ctx
408 last_close (last): last_ctx
412 : ${LTDLINCL="-I$abs_top_srcdir/libltdl"}
413 : ${LIBLTDL="$abs_builddir/../libltdl/libltdlc.la"}
415 # Skip this test when called from:
416 # make distcheck DISTCHECK_CONFIGURE_FLAGS=--disable-ltdl-install
417 AT_CHECK([case $LIBLTDL in #(
418 */_inst/lib/*) test -f "$LIBLTDL" || (exit 77) ;;
421 CPPFLAGS="$LTDLINCL $CPPFLAGS"
423 AT_CHECK([$LIBTOOL --mode=compile $CC $CPPFLAGS $CFLAGS -c module.c],
424 [], [ignore], [ignore])
425 AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o module.la ]dnl
426 [-rpath /nowhere -module -avoid-version -no-undefined ]dnl
428 [], [ignore], [ignore])
430 dnl Not possible to override the preopen loader, so skip if not shared.
432 AT_CHECK([test -n "$dlname" || (exit 77)])
434 AT_CHECK([$CC $CPPFLAGS $CFLAGS -c main.c], [], [ignore], [ignore])
435 AT_CHECK([$LIBTOOL --mode=link $CC $CFLAGS $LDFLAGS -o main$EXEEXT ]dnl
436 [main.$OBJEXT -dlopen module.la $LIBLTDL],
437 [], [ignore], [ignore])
439 LT_AT_EXEC_CHECK([./main], [], [expout], [ignore], [])