]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
virFileResolveLink: guarantee an absolute path
authorEric Blake <eblake@redhat.com>
Mon, 28 Jun 2010 21:06:36 +0000 (15:06 -0600)
committerEric Blake <eblake@redhat.com>
Tue, 29 Jun 2010 13:24:38 +0000 (07:24 -0600)
https://bugzilla.redhat.com/show_bug.cgi?id=608092

* src/util/util.c (virFileResolveLink): Use
canonicalize_file_name, rather than areadlink.

src/util/util.c

index 445fd4e7d46660f07d909cdf17e9c8203799f21e..d05811370ba53d414c1679cd4468b01d71e538d5 100644 (file)
@@ -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;
 }