[libvirt] [PATCH 18/23] util: use realpath/g_canonicalize_filename

Daniel P. Berrangé berrange at redhat.com
Thu Jan 2 14:53:52 UTC 2020


The canonicalize_file_name(path) is equivalent to calling
realpath(path, NULL). Passing NULL for the second arg of
realpath is not standardized behaviour, however, Linux,
FreeBSD > 6.4 and macOS > 10.5 all support this critical
extension.

This leaves Windows which doesn't provide realpath at all.
The g_canonicalize_filename() function doesn't expand
symlinks, so is not strictly equivalent to realpath()
but is close enough for our Windows portability needs
right now.

Signed-off-by: Daniel P. Berrangé <berrange at redhat.com>
---
 src/util/virfile.c  |  9 ++++++++-
 tests/virfilemock.c | 12 +++++++-----
 2 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/src/util/virfile.c b/src/util/virfile.c
index 9787086f3d..4fc872ef1d 100644
--- a/src/util/virfile.c
+++ b/src/util/virfile.c
@@ -3256,7 +3256,14 @@ virFileSanitizePath(const char *path)
 char *
 virFileCanonicalizePath(const char *path)
 {
-    return canonicalize_file_name(path); /* exempt from syntax-check */
+#ifdef WIN32
+    /* Does not resolve symlinks, only expands . & .. & repeated /.
+     * It will never fail, so sanitize errno to indicate success */
+    errno = 0;
+    return g_canonicalize_filename(path, NULL);
+#else
+    return realpath(path, NULL); /* exempt from syntax-check */
+#endif
 }
 
 /**
diff --git a/tests/virfilemock.c b/tests/virfilemock.c
index 65685c6d26..802ee9b5f9 100644
--- a/tests/virfilemock.c
+++ b/tests/virfilemock.c
@@ -24,6 +24,7 @@
 #if HAVE_LINUX_MAGIC_H
 # include <linux/magic.h>
 #endif
+#include <assert.h>
 
 #include "virmock.h"
 #include "virstring.h"
@@ -33,7 +34,7 @@
 
 static FILE *(*real_setmntent)(const char *filename, const char *type);
 static int (*real_statfs)(const char *path, struct statfs *buf);
-static char *(*real_canonicalize_file_name)(const char *path);
+static char *(*real_realpath)(const char *path, char *resolved);
 
 
 static void
@@ -44,7 +45,7 @@ init_syms(void)
 
     VIR_MOCK_REAL_INIT(setmntent);
     VIR_MOCK_REAL_INIT(statfs);
-    VIR_MOCK_REAL_INIT(canonicalize_file_name);
+    VIR_MOCK_REAL_INIT(realpath);
 }
 
 
@@ -116,7 +117,7 @@ statfs_mock(const char *mtab,
     /* We don't need to do this in callers because real statfs(2)
      * does that for us. However, in mocked implementation we
      * need to do this. */
-    if (!(canonPath = canonicalize_file_name(path)))
+    if (!(canonPath = realpath(path, NULL)))
         return -1;
 
     while (getmntent_r(f, &mb, mntbuf, sizeof(mntbuf))) {
@@ -178,7 +179,7 @@ statfs(const char *path, struct statfs *buf)
 
 
 char *
-canonicalize_file_name(const char *path)
+realpath(const char *path, char *resolved)
 {
 
     init_syms();
@@ -187,6 +188,7 @@ canonicalize_file_name(const char *path)
         const char *p;
         char *ret;
 
+        assert(resolved == NULL);
         if ((p = STRSKIP(path, "/some/symlink")))
             ret = g_strdup_printf("/gluster%s", p);
         else
@@ -195,5 +197,5 @@ canonicalize_file_name(const char *path)
         return ret;
     }
 
-    return real_canonicalize_file_name(path);
+    return real_realpath(path, resolved);
 }
-- 
2.24.1




More information about the libvir-list mailing list