[libvirt] [PATCH] virFileResolveLink: guarantee an absolute path

Eric Blake eblake at redhat.com
Mon Jun 28 21:09:39 UTC 2010


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




More information about the libvir-list mailing list