mirror of
https://github.com/libguestfs/libguestfs.git
synced 2026-03-21 22:53:37 +00:00
tests/c-api: Test that the library can really be loaded with dlopen.
Answer is yes, but it was good to know.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -483,6 +483,7 @@ Makefile.in
|
||||
/tests/c-api/test-config
|
||||
/tests/c-api/test-create-handle
|
||||
/tests/c-api/test-debug-to-file
|
||||
/tests/c-api/test-dlopen
|
||||
/tests/c-api/test-environment
|
||||
/tests/c-api/test-event-string
|
||||
/tests/c-api/test*.img
|
||||
|
||||
@@ -581,6 +581,13 @@ AC_ARG_WITH([extra-packages],
|
||||
[EXTRA_PACKAGES=])
|
||||
AC_SUBST([EXTRA_PACKAGES])
|
||||
|
||||
dnl Check for libdl/dlopen (optional - only used to test if the library
|
||||
dnl can be used with libdl).
|
||||
AC_CHECK_LIB([dl],[dlopen],[have_libdl=yes],[have_libdl=no])
|
||||
AC_CHECK_HEADERS([dlfcn.h],[have_dlfcn=yes],[have_dlfcn=no])
|
||||
AM_CONDITIONAL([HAVE_LIBDL],
|
||||
[test "x$have_libdl" = "xyes" && test "x$have_dlfcn" = "xyes"])
|
||||
|
||||
dnl Check for rpcgen and XDR library. rpcgen is optional.
|
||||
AC_CHECK_PROG([RPCGEN],[rpcgen],[rpcgen],[no])
|
||||
AM_CONDITIONAL([HAVE_RPCGEN],[test "x$RPCGEN" != "xno"])
|
||||
|
||||
@@ -38,11 +38,16 @@ check_PROGRAMS = \
|
||||
test-environment \
|
||||
test-pwd \
|
||||
test-event-string
|
||||
if HAVE_LIBDL
|
||||
check_PROGRAMS += \
|
||||
test-dlopen
|
||||
endif
|
||||
|
||||
TESTS = \
|
||||
tests \
|
||||
test-just-header \
|
||||
test-create-handle \
|
||||
test-dlopen \
|
||||
test-config \
|
||||
test-add-drive-opts \
|
||||
test-last-errno \
|
||||
@@ -52,6 +57,10 @@ TESTS = \
|
||||
test-debug-to-file \
|
||||
test-environment \
|
||||
test-event-string
|
||||
if HAVE_LIBDL
|
||||
TESTS += \
|
||||
test-dlopen
|
||||
endif
|
||||
|
||||
if HAVE_CXX
|
||||
check_PROGRAMS += test-just-header-cxx
|
||||
@@ -130,6 +139,17 @@ test_create_handle_CFLAGS = \
|
||||
test_create_handle_LDADD = \
|
||||
$(top_builddir)/src/libguestfs.la
|
||||
|
||||
if HAVE_LIBDL
|
||||
test_dlopen_SOURCES = test-dlopen.c
|
||||
test_dlopen_CPPFLAGS = \
|
||||
-I$(top_srcdir)/src -I$(top_builddir)/src
|
||||
test_dlopen_CFLAGS = \
|
||||
$(WARN_CFLAGS) $(WERROR_CFLAGS) \
|
||||
-DLIBRARY=\"$(top_builddir)/src/.libs/libguestfs.so.0\"
|
||||
test_dlopen_LDADD = \
|
||||
-ldl
|
||||
endif
|
||||
|
||||
test_config_SOURCES = test-config.c
|
||||
test_config_CPPFLAGS = \
|
||||
-I$(top_srcdir)/src -I$(top_builddir)/src
|
||||
|
||||
94
tests/c-api/test-dlopen.c
Normal file
94
tests/c-api/test-dlopen.c
Normal file
@@ -0,0 +1,94 @@
|
||||
/* libguestfs
|
||||
* Copyright (C) 2014 Red Hat Inc.
|
||||
*
|
||||
* This program 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.
|
||||
*
|
||||
* This program 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 this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* Test the library can be loaded and unloaded using dlopen etc. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <dlfcn.h>
|
||||
|
||||
/* We don't need the <guestfs.h> header file here. */
|
||||
typedef struct guestfs_h guestfs_h;
|
||||
|
||||
typedef guestfs_h *(*guestfs_create_t) (void);
|
||||
typedef const char * (*guestfs_get_program_t) (guestfs_h *);
|
||||
typedef void (*guestfs_close_t) (guestfs_h *);
|
||||
|
||||
#ifndef LIBRARY
|
||||
#error "-DLIBRARY was not defined"
|
||||
#endif
|
||||
|
||||
static void *
|
||||
read_symbol (void *lib, const char *symbol)
|
||||
{
|
||||
void *symval;
|
||||
const char *err;
|
||||
|
||||
dlerror (); /* Clear error indicator. */
|
||||
symval = dlsym (lib, symbol);
|
||||
if ((err = dlerror ()) != NULL) {
|
||||
fprintf (stderr, "could not read symbol: %s: %s\n", symbol, err);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
return symval;
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
void *lib;
|
||||
guestfs_create_t guestfs_create;
|
||||
guestfs_get_program_t guestfs_get_program;
|
||||
guestfs_close_t guestfs_close;
|
||||
guestfs_h *g;
|
||||
|
||||
if (access (LIBRARY, X_OK) == -1) {
|
||||
fprintf (stderr, "test skipped because %s cannot be accessed: %m\n",
|
||||
LIBRARY);
|
||||
exit (77);
|
||||
}
|
||||
|
||||
lib = dlopen (LIBRARY, RTLD_LAZY);
|
||||
if (lib == NULL) {
|
||||
fprintf (stderr, "could not open %s: %s\n", LIBRARY, dlerror ());
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
guestfs_create = read_symbol (lib, "guestfs_create");
|
||||
guestfs_get_program = read_symbol (lib, "guestfs_get_program");
|
||||
guestfs_close = read_symbol (lib, "guestfs_close");
|
||||
|
||||
g = guestfs_create ();
|
||||
if (g == NULL) {
|
||||
fprintf (stderr, "failed to create handle\n");
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
printf ("program = %s\n", guestfs_get_program (g));
|
||||
|
||||
guestfs_close (g);
|
||||
|
||||
if (dlclose (lib) != 0) {
|
||||
fprintf (stderr, "could not close %s: %s\n", LIBRARY, dlerror ());
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
exit (EXIT_SUCCESS);
|
||||
}
|
||||
Reference in New Issue
Block a user