SUBDIRS = . libkmod/docs man
+DISTCLEAN_LOCAL_HOOKS =
EXTRA_DIST =
CLEANFILES =
ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
$(LN_S) $(notdir $<) $@)
endif
+# ------------------------------------------------------------------------------
+# TESTSUITE
+# ------------------------------------------------------------------------------
+
# libtool will not create a shared library that is not installed. Workaround
# this by creating it by ourselves
CREATE_SHARED_OVERRIDE_LIB = \
testsuite/uname.so: testsuite/uname.c
$(CREATE_SHARED_OVERRIDE_LIB)
-EXTRA_DIST += testsuite/uname.c
-CLEANFILES += testsuite/uname.so
+testsuite/path.so: testsuite/path.c
+ $(CREATE_SHARED_OVERRIDE_LIB)
+
+EXTRA_DIST += testsuite/uname.c testsuite/path.c
+CLEANFILES += testsuite/uname.so testsuite/path.so
+
+testsuite/rootfs:
+ $(AM_V_GEN) tar -C testsuite/ \
+ -xJf $(top_srcdir)/testsuite/rootfs.tar.xz
+
+testsuite-distclean:
+ -rm -rf testsuite/rootfs
+
+DISTCLEAN_LOCAL_HOOKS += testsuite-distclean
+EXTRA_DIST += testsuite/rootfs.tar.xz
check_LTLIBRARIES = testsuite/libtestsuite.la
testsuite_libtestsuite_la_SOURCES = testsuite/testsuite.c \
testsuite/testsuite.h
-testsuite_libtestsuite_la_DEPENDENCIES = testsuite/uname.so
+testsuite_libtestsuite_la_DEPENDENCIES = testsuite/uname.so \
+ testsuite/path.so \
+ testsuite/rootfs
+testsuite_test_testsuite_CPPFLAGS = $(AM_CPPFLAGS) \
+ -DTESTSUITE_ROOTFS=\"$(abs_top_builddir)/testsuite/rootfs/\"
TESTSUITE = testsuite/test-init testsuite/test-testsuite
check_PROGRAMS = $(TESTSUITE)
DISTCHECK_CONFIGURE_FLAGS=--enable-gtk-doc
+distclean-local: $(DISTCLEAN_LOCAL_HOOKS)
# ------------------------------------------------------------------------------
# custom release helpers
*.so
test-testsuite
test-init
+rootfs/
--- /dev/null
+#include <assert.h>
+#include <errno.h>
+#include <dlfcn.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "testsuite.h"
+
+static void *nextlib;
+static const char *rootpath;
+static size_t rootpathlen;
+
+static inline bool need_trap(const char *path)
+{
+ return path != NULL && path[0] == '/';
+}
+
+static const char *trap_path(const char *path, char buf[PATH_MAX * 2])
+{
+ size_t len;
+
+ if (!need_trap(path))
+ return path;
+
+ len = strlen(path);
+
+ if (len + rootpathlen > PATH_MAX * 2) {
+ errno = ENAMETOOLONG;
+ return NULL;
+ }
+
+ memcpy(buf, rootpath, rootpathlen);
+ strcpy(buf + rootpathlen, path);
+ return buf;
+}
+
+static bool get_rootpath(const char *f)
+{
+ if (rootpath != NULL)
+ return true;
+
+ rootpath = getenv(S_TC_ROOTFS);
+ if (rootpath == NULL) {
+ ERR("TRAP %s(): missing export %s?\n", f, S_TC_ROOTFS);
+ errno = ENOENT;
+ return false;
+ }
+
+ rootpathlen = strlen(rootpath);
+
+ return true;
+}
+
+static void *get_libc_func(const char *f)
+{
+ void *fp;
+
+ if (nextlib == NULL) {
+#ifdef RTLD_NEXT
+ nextlib = RTLD_NEXT;
+#else
+ nextlib = dlopen("libc.so.6", RTLD_LAZY);
+#endif
+ }
+
+ fp = dlsym(nextlib, f);
+ assert(fp);
+
+ return fp;
+}
+
+TS_EXPORT FILE *fopen(const char *path, const char *mode)
+{
+ const char *p;
+ char buf[PATH_MAX * 2];
+ static int (*_fopen)(const char *path, const char *mode);
+
+ if (!get_rootpath(__func__))
+ return NULL;
+
+ _fopen = get_libc_func("fopen");
+
+ p = trap_path(path, buf);
+ if (p == NULL)
+ return NULL;
+
+ return (void *) (long) (*_fopen)(p, mode);
+}
.need_spawn = true,
};
+static int testsuite_rootfs_fopen(const struct test *t)
+{
+ FILE *fp;
+ char s[100];
+ int n;
+
+ fp = fopen("/lib/modules/a", "r");
+ if (fp == NULL)
+ return EXIT_FAILURE;;
+
+ n = fscanf(fp, "%s", s);
+ if (n != 1)
+ return EXIT_FAILURE;
+
+ if (strcmp(s, "kmod-test-chroot-works") != 0)
+ return EXIT_FAILURE;
+
+ return EXIT_SUCCESS;
+}
+static const struct test stestsuite_rootfs_fopen = {
+ .name = "testsuite_rootfs_fopen",
+ .description = "test if rootfs works - fopen()",
+ .func = testsuite_rootfs_fopen,
+ .config = {
+ [TC_ROOTFS] = TESTSUITE_ROOTFS "test-rootfs/",
+ },
+ .need_spawn = true,
+};
+
static const struct test *tests[] = {
&stestsuite_uname,
+ &stestsuite_rootfs_fopen,
NULL,
};
_TC_LAST,
};
+#define S_TC_ROOTFS "TESTSUITE_ROOTFS"
#define S_TC_UNAME_R "TESTSUITE_UNAME_R"