tree-wide: stop using canonicalize_file_name(), use chase_symlinks() instead

Let's use chase_symlinks() everywhere, and stop using GNU
canonicalize_file_name() everywhere. For most cases this should not change
behaviour, however increase exposure of our function to get better tested. Most
importantly in a few cases (most notably nspawn) it can take the correct root
directory into account when chasing symlinks.
This commit is contained in:
Lennart Poettering
2016-12-01 00:25:51 +01:00
parent c9d5c9c0e1
commit e187369587
21 changed files with 135 additions and 117 deletions
+13 -13
View File
@@ -224,25 +224,25 @@ int readlink_and_make_absolute(const char *p, char **r) {
return 0;
}
int readlink_and_canonicalize(const char *p, char **r) {
int readlink_and_canonicalize(const char *p, const char *root, char **ret) {
char *t, *s;
int j;
int r;
assert(p);
assert(r);
assert(ret);
j = readlink_and_make_absolute(p, &t);
if (j < 0)
return j;
r = readlink_and_make_absolute(p, &t);
if (r < 0)
return r;
s = canonicalize_file_name(t);
if (s) {
r = chase_symlinks(t, root, &s);
if (r < 0)
/* If we can't follow up, then let's return the original string, slightly cleaned up. */
*ret = path_kill_slashes(t);
else {
*ret = s;
free(t);
*r = s;
} else
*r = t;
path_kill_slashes(*r);
}
return 0;
}
+1 -1
View File
@@ -39,7 +39,7 @@ int readlinkat_malloc(int fd, const char *p, char **ret);
int readlink_malloc(const char *p, char **r);
int readlink_value(const char *p, char **ret);
int readlink_and_make_absolute(const char *p, char **r);
int readlink_and_canonicalize(const char *p, char **r);
int readlink_and_canonicalize(const char *p, const char *root, char **r);
int readlink_and_make_absolute_root(const char *root, const char *path, char **ret);
int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid);
+8 -6
View File
@@ -29,6 +29,7 @@
#include "escape.h"
#include "fd-util.h"
#include "fileio.h"
#include "fs-util.h"
#include "hashmap.h"
#include "mount-util.h"
#include "parse-util.h"
@@ -205,9 +206,10 @@ fallback_fstat:
}
/* flags can be AT_SYMLINK_FOLLOW or 0 */
int path_is_mount_point(const char *t, int flags) {
_cleanup_close_ int fd = -1;
int path_is_mount_point(const char *t, const char *root, int flags) {
_cleanup_free_ char *canonical = NULL, *parent = NULL;
_cleanup_close_ int fd = -1;
int r;
assert(t);
@@ -219,9 +221,9 @@ int path_is_mount_point(const char *t, int flags) {
* /bin -> /usr/bin/ and /usr is a mount point, then the parent that we
* look at needs to be /usr, not /. */
if (flags & AT_SYMLINK_FOLLOW) {
canonical = canonicalize_file_name(t);
if (!canonical)
return -errno;
r = chase_symlinks(t, root, &canonical);
if (r < 0)
return r;
t = canonical;
}
@@ -473,7 +475,7 @@ int bind_remount_recursive(const char *prefix, bool ro, char **blacklist) {
return r;
/* Deal with mount points that are obstructed by a later mount */
r = path_is_mount_point(x, 0);
r = path_is_mount_point(x, NULL, 0);
if (r == -ENOENT || r == 0)
continue;
if (r < 0)
+1 -1
View File
@@ -30,7 +30,7 @@
#include "missing.h"
int fd_is_mount_point(int fd, const char *filename, int flags);
int path_is_mount_point(const char *path, int flags);
int path_is_mount_point(const char *path, const char *root, int flags);
int repeat_unmount(const char *path, int flags);
+22 -23
View File
@@ -220,10 +220,11 @@ int path_strv_make_absolute_cwd(char **l) {
return 0;
}
char **path_strv_resolve(char **l, const char *prefix) {
char **path_strv_resolve(char **l, const char *root) {
char **s;
unsigned k = 0;
bool enomem = false;
int r;
if (strv_isempty(l))
return l;
@@ -233,17 +234,17 @@ char **path_strv_resolve(char **l, const char *prefix) {
* changes on failure. */
STRV_FOREACH(s, l) {
char *t, *u;
_cleanup_free_ char *orig = NULL;
char *t, *u;
if (!path_is_absolute(*s)) {
free(*s);
continue;
}
if (prefix) {
if (root) {
orig = *s;
t = strappend(prefix, orig);
t = prefix_root(root, orig);
if (!t) {
enomem = true;
continue;
@@ -251,28 +252,26 @@ char **path_strv_resolve(char **l, const char *prefix) {
} else
t = *s;
errno = 0;
u = canonicalize_file_name(t);
if (!u) {
if (errno == ENOENT) {
if (prefix) {
u = orig;
orig = NULL;
free(t);
} else
u = t;
} else {
r = chase_symlinks(t, root, &u);
if (r == -ENOENT) {
if (root) {
u = orig;
orig = NULL;
free(t);
if (errno == ENOMEM || errno == 0)
enomem = true;
} else
u = t;
} else if (r < 0) {
free(t);
continue;
}
} else if (prefix) {
if (r == -ENOMEM)
enomem = true;
continue;
} else if (root) {
char *x;
free(t);
x = path_startswith(u, prefix);
x = path_startswith(u, root);
if (x) {
/* restore the slash if it was lost */
if (!startswith(x, "/"))
@@ -304,12 +303,12 @@ char **path_strv_resolve(char **l, const char *prefix) {
return l;
}
char **path_strv_resolve_uniq(char **l, const char *prefix) {
char **path_strv_resolve_uniq(char **l, const char *root) {
if (strv_isempty(l))
return l;
if (!path_strv_resolve(l, prefix))
if (!path_strv_resolve(l, root))
return NULL;
return strv_uniq(l);
+2 -2
View File
@@ -66,8 +66,8 @@ static inline bool path_equal_ptr(const char *a, const char *b) {
})
int path_strv_make_absolute_cwd(char **l);
char** path_strv_resolve(char **l, const char *prefix);
char** path_strv_resolve_uniq(char **l, const char *prefix);
char** path_strv_resolve(char **l, const char *root);
char** path_strv_resolve_uniq(char **l, const char *root);
int find_binary(const char *name, char **filename);