Extend virFindFileInPath to search in custom extra paths as well. Some binaries that libvirt needs are not usually in $PATH so we need to have a way to look for these as well. Signed-off-by: Pavel Hrdina <phrdina@xxxxxxxxxx> --- src/libvirt_private.syms | 2 +- src/util/virfile.c | 16 ++++++++++++++-- src/util/virfile.h | 5 ++++- tests/domaincapsmock.c | 3 ++- tests/virfirewallmock.c | 3 ++- 5 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index abd3dc4bd1..717686ddee 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2254,7 +2254,7 @@ virFileWrapperFdClose; virFileWrapperFdFree; virFileWrapperFdNew; virFileWriteStr; -virFindFileInPath; +virFindFileInPathFull; # util/virfilecache.h diff --git a/src/util/virfile.c b/src/util/virfile.c index 03a7725dd3..7922fda2e5 100644 --- a/src/util/virfile.c +++ b/src/util/virfile.c @@ -1654,13 +1654,15 @@ virFileIsLink(const char *linkpath) } /* - * Finds a requested executable file in the PATH env. e.g.: + * Finds a requested executable file in the paths provided by @extra_paths + * argument or in PATH env. e.g.: * "qemu-img" will return "/usr/bin/qemu-img" * * You must free the result */ char * -virFindFileInPath(const char *file) +virFindFileInPathFull(const char *file, + const GStrv extra_paths) { const char *origpath = NULL; g_auto(GStrv) paths = NULL; @@ -1692,6 +1694,16 @@ virFindFileInPath(const char *file) return abspath; } + /* First search in paths provided by caller. + */ + if (extra_paths) { + for (pathiter = extra_paths; *pathiter; pathiter++) { + g_autofree char *fullpath = g_strdup_printf("%s/%s", *pathiter, file); + if (virFileIsExecutable(fullpath)) + return g_steal_pointer(&fullpath); + } + } + /* copy PATH env so we can tweak it */ origpath = getenv("PATH"); if (!origpath) diff --git a/src/util/virfile.h b/src/util/virfile.h index b9f7b1766f..eee27c2efc 100644 --- a/src/util/virfile.h +++ b/src/util/virfile.h @@ -184,9 +184,12 @@ int virFileResolveAllLinks(const char *linkpath, int virFileIsLink(const char *linkpath) ATTRIBUTE_NONNULL(1) G_GNUC_WARN_UNUSED_RESULT; -char *virFindFileInPath(const char *file) +char *virFindFileInPathFull(const char *file, + const GStrv extra_paths) G_GNUC_NO_INLINE; +#define virFindFileInPath(file) virFindFileInPathFull(file, NULL) + char *virFileFindResource(const char *filename, const char *builddir, const char *installdir) diff --git a/tests/domaincapsmock.c b/tests/domaincapsmock.c index 73690f0b9e..4bef2b72d0 100644 --- a/tests/domaincapsmock.c +++ b/tests/domaincapsmock.c @@ -43,7 +43,8 @@ virHostCPUGetMicrocodeVersion(virArch hostArch G_GNUC_UNUSED) } char * -virFindFileInPath(const char *file) +virFindFileInPathFull(const char *file, + const GStrv extra_args G_GNUC_UNUSED) { if (g_str_has_prefix(file, "qemu-system") || g_str_equal(file, "qemu-kvm")) { diff --git a/tests/virfirewallmock.c b/tests/virfirewallmock.c index 6b096701c9..a047e56bd9 100644 --- a/tests/virfirewallmock.c +++ b/tests/virfirewallmock.c @@ -20,7 +20,8 @@ #include "virfile.h" char * -virFindFileInPath(const char *file) +virFindFileInPathFull(const char *file, + const GStrv extra_args G_GNUC_UNUSED) { if (file && (g_strrstr(file, "ebtables") || -- 2.30.2