Add virFileFindResource which will try to locate files
in the local build tree if the calling binary (eg libvirtd or
test suite) is being run from the build tree. The corresponding
virFileActivateDirOverride should be called at startup passing
in argv[0]. This will be examined for evidence of libtool magic
binary prefix / sub-directory in order to activate the override.
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
src/Makefile.am | 2 ++
src/libvirt_private.syms | 3 ++
src/util/virfile.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++
src/util/virfile.h | 11 +++++++
4 files changed, 99 insertions(+)
diff --git a/src/Makefile.am b/src/Makefile.am
index 21d56fc..5fb9e88 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -18,6 +18,7 @@
# old automake does not provide abs_{src,build}dir variables
abs_builddir = $(shell pwd)
+abs_topbuilddir = $(shell cd .. && pwd)
abs_srcdir = $(shell cd $(srcdir) && pwd)
# No libraries with the exception of LIBXML should be listed
@@ -30,6 +31,7 @@ INCLUDES = -I../gnulib/lib \
-I$(top_srcdir)/include \
-I$(top_srcdir)/src/util \
-DIN_LIBVIRT \
+ -Dabs_topbuilddir="\"$(abs_topbuilddir)\"" \
$(GETTEXT_CPPFLAGS)
AM_CFLAGS = $(LIBXML_CFLAGS) \
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 53dbdb4..1c7dd72 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1222,6 +1222,7 @@ virBuildPathInternal;
virDirCreate;
virFileAbsPath;
virFileAccessibleAs;
+virFileActivateDirOverride;
virFileBuildPath;
virFileClose;
virFileDeleteTree;
@@ -1230,6 +1231,8 @@ virFileExists;
virFileFclose;
virFileFdopen;
virFileFindMountPoint;
+virFileFindResource;
+virFileFindResourceFull;
virFileGetMountReverseSubtree;
virFileGetMountSubtree;
virFileHasSuffix;
diff --git a/src/util/virfile.c b/src/util/virfile.c
index cffcbc1..c7cf84a 100644
--- a/src/util/virfile.c
+++ b/src/util/virfile.c
@@ -1542,6 +1542,89 @@ virFindFileInPath(const char *file)
return fullpath;
}
+
+static bool useDirOverride = false;
+
+/**
+ * virFileFindResourceFull:
+ * @filename: libvirt distributed filename without any path
+ * @prefix: optional string to prepend to filename
+ * @suffix: optional string to append to filename
+ * @builddir: location of the binary in the source tree build tree
+ * @installdir: location of the installed binary
+ * @envname: environment variable used to override all dirs
+ *
+ * A helper which will return a path to @filename within
+ * the current build tree, if the calling binary is being
+ * run from the source tree. Otherwise it will return the
+ * path in the installed location.
+ *
+ * If @envname is none-NULL it will override all other
+ * directory lookup
+ *
+ * Only use this with @filename files that are part of
+ * the libvirt tree, not 3rd party binaries/files.
+ */
+char *virFileFindResourceFull(const char *filename,
+ const char *prefix,
+ const char *suffix,
+ const char *builddir,
+ const char *installdir,
+ const char *envname)
+{
+ char *ret = NULL;
+ const char *envval = envname ? virGetEnvBlockSUID(envname) : NULL;
+
+ if (!prefix)
+ prefix = "";
+ if (!suffix)
+ suffix = "";
+
+ if (envval) {
+ if (virAsprintf(&ret, "%s/%s%s%s", envval, prefix, filename,
suffix) < 0)
+ return NULL;
+ } else if (useDirOverride) {
+ if (virAsprintf(&ret, "%s/%s/%s%s%s", abs_topbuilddir, builddir,
prefix, filename, suffix) < 0)
+ return NULL;
+ } else {
+ if (virAsprintf(&ret, "%s/%s%s%s", installdir, prefix, filename,
suffix) < 0)
+ return NULL;
+ }
+
+ VIR_DEBUG("Resolved '%s' to '%s'", filename, ret);
+ return ret;
+}
+
+char *
+virFileFindResource(const char *filename,
+ const char *builddir,
+ const char *installdir)
+{
+ return virFileFindResourceFull(filename, NULL, NULL, builddir, installdir, NULL);
+}
+
+
+/**
+ * virFileActivateDirOverride:
+ * @argv0: argv[0] of the calling program
+ *
+ * Look at @argv0 and try to detect if running from
+ * a build directory, by looking for a 'lt-' prefix
+ * on the binary name, or '/.libs/' in the path
+ */
+void virFileActivateDirOverride(const char *argv0)
+{
+ char *file = strrchr(argv0, '/');
+ if (!file || file[1] == '\0')
+ return;
+ file++;
+ if (STRPREFIX(file, "lt-") ||
+ strstr(argv0, "/.libs/")) {
+ useDirOverride = true;
+ VIR_DEBUG("Activating build dir override for %s", argv0);
+ }
+}
+
bool
virFileIsDir(const char *path)
{
diff --git a/src/util/virfile.h b/src/util/virfile.h
index 46ef781..d5227d1 100644
--- a/src/util/virfile.h
+++ b/src/util/virfile.h
@@ -160,6 +160,17 @@ int virFileIsLink(const char *linkpath)
char *virFindFileInPath(const char *file);
+char *virFileFindResource(const char *filename,
+ const char *builddir,
+ const char *installdir);
+char *virFileFindResourceFull(const char *filename,
+ const char *prefix,
+ const char *suffix,
+ const char *builddir,
+ const char *installdir,
+ const char *envname);
+void virFileActivateDirOverride(const char *argv0);
+
bool virFileIsDir (const char *file) ATTRIBUTE_NONNULL(1);
bool virFileExists(const char *file) ATTRIBUTE_NONNULL(1);
bool virFileIsExecutable(const char *file) ATTRIBUTE_NONNULL(1);
--
1.9.0