diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 62c296bf5f..27b8e111aa 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2358,6 +2358,7 @@ virFileWrapperFdFree; virFileWrapperFdNew; virFileWriteStr; virFindFileInPath; +virFindFileInPathFull; # util/virfilecache.h diff --git a/src/util/virfile.c b/src/util/virfile.c index 8e94d19e45..6b4d4c3522 100644 --- a/src/util/virfile.c +++ b/src/util/virfile.c @@ -1737,6 +1737,25 @@ virFileIsLink(const char *linkpath) */ char * virFindFileInPath(const char *file) +{ + return virFindFileInPathFull(file, NULL); +} + +/* virFindFileInPathFull: + * @file: name of the program + * @extraDirs: NULL-terminated list of additional directories + * + * Like virFindFileInPath(), but in addition to searching $PATH also + * looks into all directories listed in @extraDirs. This is useful to + * locate helpers that are installed outside of $PATH. + * + * The returned path must be freed by the caller. + * + * Returns: absolute path of the program or NULL + */ +char * +virFindFileInPathFull(const char *file, + const char *const *extraDirs) { g_autofree char *path = NULL; if (file == NULL) @@ -1751,6 +1770,20 @@ virFindFileInPath(const char *file) return g_canonicalize_filename(path, NULL); } + if (extraDirs) { + while (*extraDirs) { + g_autofree char *extraPath = NULL; + + extraPath = g_strdup_printf("%s/%s", *extraDirs, file); + + if (virFileIsExecutable(extraPath)) { + return g_steal_pointer(&extraPath); + } + + extraDirs++; + } + } + return NULL; } diff --git a/src/util/virfile.h b/src/util/virfile.h index f7a31d9f57..6a14173625 100644 --- a/src/util/virfile.h +++ b/src/util/virfile.h @@ -189,6 +189,9 @@ int virFileIsLink(const char *linkpath) char *virFindFileInPath(const char *file) G_NO_INLINE; +char *virFindFileInPathFull(const char *file, + const char *const *extraDirs) + G_NO_INLINE; char *virFileFindResource(const char *filename, const char *builddir,