https://bugzilla.redhat.com/show_bug.cgi?id=608092 * src/util/util.c (virFileResolveLink): Use canonicalize_file_name, rather than areadlink. --- For this patch, I chose to avoid any symlink resolution if an lstat shows the last element doesn't need any; but if we know we need symlink resolution, it is much easier to use existing interfaces to correctly resolve relative paths, even if it ends up doing more resolution work than what we strictly need. src/util/util.c | 26 ++++++++++++++++---------- 1 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/util/util.c b/src/util/util.c index 445fd4e..d058113 100644 --- a/src/util/util.c +++ b/src/util/util.c @@ -63,7 +63,7 @@ # include <mntent.h> #endif -#include "areadlink.h" +#include "dirname.h" #include "virterror_internal.h" #include "logging.h" #include "event.h" @@ -1178,8 +1178,9 @@ int virFileLinkPointsTo(const char *checkLink, /* - * Attempt to resolve a symbolic link, returning the - * real path + * Attempt to resolve a symbolic link, returning an + * absolute path where only the last component is guaranteed + * not to be a symlink. * * Return 0 if path was not a symbolic, or the link was * resolved. Return -1 with errno set upon error @@ -1191,16 +1192,21 @@ int virFileResolveLink(const char *linkpath, *resultpath = NULL; - if (lstat(linkpath, &st) < 0) - return -1; - - if (!S_ISLNK(st.st_mode)) { - if (!(*resultpath = strdup(linkpath))) + /* We don't need the full canonicalization of intermediate + * directories, if linkpath is absolute and the basename is + * already a non-symlink. */ + if (IS_ABSOLUTE_FILE_NAME(linkpath)) { + if (lstat(linkpath, &st) < 0) return -1; - return 0; + + if (!S_ISLNK(st.st_mode)) { + if (!(*resultpath = strdup(linkpath))) + return -1; + return 0; + } } - *resultpath = areadlink (linkpath); + *resultpath = canonicalize_file_name(linkpath); return *resultpath == NULL ? -1 : 0; } -- 1.7.0.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list