util: use realpath/g_canonicalize_filename

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.

Reviewed-by: Fabiano Fidêncio <fidencio@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
This commit is contained in:
Daniel P. Berrangé 2019-12-23 14:21:54 +00:00
parent 0b4598b183
commit b4d601ba87
2 changed files with 15 additions and 6 deletions

View File

@ -3256,7 +3256,14 @@ virFileSanitizePath(const char *path)
char * char *
virFileCanonicalizePath(const char *path) 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
} }
/** /**

View File

@ -24,6 +24,7 @@
#if HAVE_LINUX_MAGIC_H #if HAVE_LINUX_MAGIC_H
# include <linux/magic.h> # include <linux/magic.h>
#endif #endif
#include <assert.h>
#include "virmock.h" #include "virmock.h"
#include "virstring.h" #include "virstring.h"
@ -33,7 +34,7 @@
static FILE *(*real_setmntent)(const char *filename, const char *type); static FILE *(*real_setmntent)(const char *filename, const char *type);
static int (*real_statfs)(const char *path, struct statfs *buf); 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 static void
@ -44,7 +45,7 @@ init_syms(void)
VIR_MOCK_REAL_INIT(setmntent); VIR_MOCK_REAL_INIT(setmntent);
VIR_MOCK_REAL_INIT(statfs); 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) /* We don't need to do this in callers because real statfs(2)
* does that for us. However, in mocked implementation we * does that for us. However, in mocked implementation we
* need to do this. */ * need to do this. */
if (!(canonPath = canonicalize_file_name(path))) if (!(canonPath = realpath(path, NULL)))
return -1; return -1;
while (getmntent_r(f, &mb, mntbuf, sizeof(mntbuf))) { while (getmntent_r(f, &mb, mntbuf, sizeof(mntbuf))) {
@ -178,7 +179,7 @@ statfs(const char *path, struct statfs *buf)
char * char *
canonicalize_file_name(const char *path) realpath(const char *path, char *resolved)
{ {
init_syms(); init_syms();
@ -187,6 +188,7 @@ canonicalize_file_name(const char *path)
const char *p; const char *p;
char *ret; char *ret;
assert(resolved == NULL);
if ((p = STRSKIP(path, "/some/symlink"))) if ((p = STRSKIP(path, "/some/symlink")))
ret = g_strdup_printf("/gluster%s", p); ret = g_strdup_printf("/gluster%s", p);
else else
@ -195,5 +197,5 @@ canonicalize_file_name(const char *path)
return ret; return ret;
} }
return real_canonicalize_file_name(path); return real_realpath(path, resolved);
} }