Merge pull request #29193 from keszybz/path-util-adjustment
Make unit mangling follow paths
This commit is contained in:
+6
-15
@@ -978,6 +978,7 @@ int cg_is_empty_recursive(const char *controller, const char *path) {
|
||||
|
||||
int cg_split_spec(const char *spec, char **ret_controller, char **ret_path) {
|
||||
_cleanup_free_ char *controller = NULL, *path = NULL;
|
||||
int r;
|
||||
|
||||
assert(spec);
|
||||
|
||||
@@ -986,11 +987,9 @@ int cg_split_spec(const char *spec, char **ret_controller, char **ret_path) {
|
||||
return -EINVAL;
|
||||
|
||||
if (ret_path) {
|
||||
path = strdup(spec);
|
||||
if (!path)
|
||||
return -ENOMEM;
|
||||
|
||||
path_simplify(path);
|
||||
r = path_simplify_alloc(spec, &path);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -1037,22 +1036,14 @@ int cg_split_spec(const char *spec, char **ret_controller, char **ret_path) {
|
||||
|
||||
int cg_mangle_path(const char *path, char **result) {
|
||||
_cleanup_free_ char *c = NULL, *p = NULL;
|
||||
char *t;
|
||||
int r;
|
||||
|
||||
assert(path);
|
||||
assert(result);
|
||||
|
||||
/* First, check if it already is a filesystem path */
|
||||
if (path_startswith(path, "/sys/fs/cgroup")) {
|
||||
|
||||
t = strdup(path);
|
||||
if (!t)
|
||||
return -ENOMEM;
|
||||
|
||||
*result = path_simplify(t);
|
||||
return 0;
|
||||
}
|
||||
if (path_startswith(path, "/sys/fs/cgroup"))
|
||||
return path_simplify_alloc(path, result);
|
||||
|
||||
/* Otherwise, treat it as cg spec */
|
||||
r = cg_split_spec(path, &c, &p);
|
||||
|
||||
+8
-14
@@ -1110,6 +1110,7 @@ int search_and_fopen(
|
||||
char **ret_path) {
|
||||
|
||||
_cleanup_strv_free_ char **copy = NULL;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(mode);
|
||||
@@ -1123,13 +1124,9 @@ int search_and_fopen(
|
||||
return -errno;
|
||||
|
||||
if (ret_path) {
|
||||
char *p;
|
||||
|
||||
p = strdup(filename);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
|
||||
*ret_path = path_simplify(p);
|
||||
r = path_simplify_alloc(filename, ret_path);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
*ret = TAKE_PTR(f);
|
||||
@@ -1152,6 +1149,7 @@ int search_and_fopen_nulstr(
|
||||
char **ret_path) {
|
||||
|
||||
_cleanup_strv_free_ char **s = NULL;
|
||||
int r;
|
||||
|
||||
if (path_is_absolute(filename)) {
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
@@ -1161,13 +1159,9 @@ int search_and_fopen_nulstr(
|
||||
return -errno;
|
||||
|
||||
if (ret_path) {
|
||||
char *p;
|
||||
|
||||
p = strdup(filename);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
|
||||
*ret_path = path_simplify(p);
|
||||
r = path_simplify_alloc(filename, ret_path);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
*ret = TAKE_PTR(f);
|
||||
|
||||
+41
-21
@@ -40,7 +40,7 @@ int path_split_and_make_absolute(const char *p, char ***ret) {
|
||||
return r;
|
||||
}
|
||||
|
||||
char *path_make_absolute(const char *p, const char *prefix) {
|
||||
char* path_make_absolute(const char *p, const char *prefix) {
|
||||
assert(p);
|
||||
|
||||
/* Makes every item in the list an absolute path by prepending
|
||||
@@ -132,11 +132,9 @@ int path_make_relative(const char *from, const char *to, char **ret) {
|
||||
return -ENOMEM;
|
||||
} else {
|
||||
/* 'to' is inside of 'from'. */
|
||||
result = strdup(t);
|
||||
if (!result)
|
||||
return -ENOMEM;
|
||||
|
||||
path_simplify(result);
|
||||
r = path_simplify_alloc(t, &result);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (!path_is_valid(result))
|
||||
return -EINVAL;
|
||||
@@ -252,7 +250,7 @@ int path_strv_make_absolute_cwd(char **l) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
char **path_strv_resolve(char **l, const char *root) {
|
||||
char** path_strv_resolve(char **l, const char *root) {
|
||||
unsigned k = 0;
|
||||
bool enomem = false;
|
||||
int r;
|
||||
@@ -333,7 +331,7 @@ char **path_strv_resolve(char **l, const char *root) {
|
||||
return l;
|
||||
}
|
||||
|
||||
char **path_strv_resolve_uniq(char **l, const char *root) {
|
||||
char** path_strv_resolve_uniq(char **l, const char *root) {
|
||||
|
||||
if (strv_isempty(l))
|
||||
return l;
|
||||
@@ -344,9 +342,9 @@ char **path_strv_resolve_uniq(char **l, const char *root) {
|
||||
return strv_uniq(l);
|
||||
}
|
||||
|
||||
char *path_simplify_full(char *path, PathSimplifyFlags flags) {
|
||||
bool add_slash = false, keep_trailing_slash;
|
||||
char *f = ASSERT_PTR(path);
|
||||
char* path_simplify_full(char *path, PathSimplifyFlags flags) {
|
||||
bool add_slash = false, keep_trailing_slash, absolute, beginning = true;
|
||||
char *f = path;
|
||||
int r;
|
||||
|
||||
/* Removes redundant inner and trailing slashes. Also removes unnecessary dots.
|
||||
@@ -354,6 +352,8 @@ char *path_simplify_full(char *path, PathSimplifyFlags flags) {
|
||||
*
|
||||
* ///foo//./bar/. becomes /foo/bar
|
||||
* .//./foo//./bar/. becomes foo/bar
|
||||
* /../foo/bar becomes /foo/bar
|
||||
* /../foo/bar/.. becomes /foo/bar/..
|
||||
*/
|
||||
|
||||
if (isempty(path))
|
||||
@@ -361,8 +361,8 @@ char *path_simplify_full(char *path, PathSimplifyFlags flags) {
|
||||
|
||||
keep_trailing_slash = FLAGS_SET(flags, PATH_SIMPLIFY_KEEP_TRAILING_SLASH) && endswith(path, "/");
|
||||
|
||||
if (path_is_absolute(path))
|
||||
f++;
|
||||
absolute = path_is_absolute(path);
|
||||
f += absolute; /* Keep leading /, if present. */
|
||||
|
||||
for (const char *p = f;;) {
|
||||
const char *e;
|
||||
@@ -371,11 +371,17 @@ char *path_simplify_full(char *path, PathSimplifyFlags flags) {
|
||||
if (r == 0)
|
||||
break;
|
||||
|
||||
if (r > 0 && absolute && beginning && path_startswith(e, ".."))
|
||||
/* If we're at the beginning of an absolute path, we can safely skip ".." */
|
||||
continue;
|
||||
|
||||
beginning = false;
|
||||
|
||||
if (add_slash)
|
||||
*f++ = '/';
|
||||
|
||||
if (r < 0) {
|
||||
/* if path is invalid, then refuse to simplify remaining part. */
|
||||
/* if path is invalid, then refuse to simplify the remaining part. */
|
||||
memmove(f, p, strlen(p) + 1);
|
||||
return path;
|
||||
}
|
||||
@@ -397,7 +403,7 @@ char *path_simplify_full(char *path, PathSimplifyFlags flags) {
|
||||
return path;
|
||||
}
|
||||
|
||||
char *path_startswith_full(const char *path, const char *prefix, bool accept_dot_dot) {
|
||||
char* path_startswith_full(const char *path, const char *prefix, bool accept_dot_dot) {
|
||||
assert(path);
|
||||
assert(prefix);
|
||||
|
||||
@@ -657,7 +663,14 @@ static int find_executable_impl(const char *name, const char *root, char **ret_f
|
||||
return 0;
|
||||
}
|
||||
|
||||
int find_executable_full(const char *name, const char *root, char **exec_search_path, bool use_path_envvar, char **ret_filename, int *ret_fd) {
|
||||
int find_executable_full(
|
||||
const char *name,
|
||||
const char *root,
|
||||
char **exec_search_path,
|
||||
bool use_path_envvar,
|
||||
char **ret_filename,
|
||||
int *ret_fd) {
|
||||
|
||||
int last_error = -ENOENT, r = 0;
|
||||
const char *p = NULL;
|
||||
|
||||
@@ -807,7 +820,7 @@ int fsck_exists_for_fstype(const char *fstype) {
|
||||
return executable_is_good(checker);
|
||||
}
|
||||
|
||||
static const char *skip_slash_or_dot(const char *p) {
|
||||
static const char* skip_slash_or_dot(const char *p) {
|
||||
for (; !isempty(p); p++) {
|
||||
if (*p == '/')
|
||||
continue;
|
||||
@@ -891,7 +904,7 @@ int path_find_first_component(const char **p, bool accept_dot_dot, const char **
|
||||
return len;
|
||||
}
|
||||
|
||||
static const char *skip_slash_or_dot_backward(const char *path, const char *q) {
|
||||
static const char* skip_slash_or_dot_backward(const char *path, const char *q) {
|
||||
assert(path);
|
||||
assert(!q || q >= path);
|
||||
|
||||
@@ -1000,7 +1013,7 @@ int path_find_last_component(const char *path, bool accept_dot_dot, const char *
|
||||
return len;
|
||||
}
|
||||
|
||||
const char *last_path_component(const char *path) {
|
||||
const char* last_path_component(const char *path) {
|
||||
|
||||
/* Finds the last component of the path, preserving the optional trailing slash that signifies a directory.
|
||||
*
|
||||
@@ -1272,9 +1285,16 @@ bool hidden_or_backup_file(const char *filename) {
|
||||
bool is_device_path(const char *path) {
|
||||
|
||||
/* Returns true for paths that likely refer to a device, either by path in sysfs or to something in
|
||||
* /dev. */
|
||||
* /dev. This accepts any path that starts with /dev/ or /sys/ and has something after that prefix.
|
||||
* It does not actually resolve the path.
|
||||
*
|
||||
* Examples:
|
||||
* /dev/sda, /dev/sda/foo, /sys/class, /dev/.., /sys/.., /./dev/foo → yes.
|
||||
* /../dev/sda, /dev, /sys, /usr/path, /usr/../dev/sda → no.
|
||||
*/
|
||||
|
||||
return PATH_STARTSWITH_SET(path, "/dev/", "/sys/");
|
||||
const char *p = PATH_STARTSWITH_SET(ASSERT_PTR(path), "/dev/", "/sys/");
|
||||
return !isempty(p);
|
||||
}
|
||||
|
||||
bool valid_device_node_path(const char *path) {
|
||||
|
||||
+20
-4
@@ -53,7 +53,7 @@ int safe_getcwd(char **ret);
|
||||
int path_make_absolute_cwd(const char *p, char **ret);
|
||||
int path_make_relative(const char *from, const char *to, char **ret);
|
||||
int path_make_relative_parent(const char *from_child, const char *to, char **ret);
|
||||
char *path_startswith_full(const char *path, const char *prefix, bool accept_dot_dot) _pure_;
|
||||
char* path_startswith_full(const char *path, const char *prefix, bool accept_dot_dot) _pure_;
|
||||
static inline char* path_startswith(const char *path, const char *prefix) {
|
||||
return path_startswith_full(path, prefix, true);
|
||||
}
|
||||
@@ -80,11 +80,27 @@ typedef enum PathSimplifyFlags {
|
||||
PATH_SIMPLIFY_KEEP_TRAILING_SLASH = 1 << 0,
|
||||
} PathSimplifyFlags;
|
||||
|
||||
char *path_simplify_full(char *path, PathSimplifyFlags flags);
|
||||
char* path_simplify_full(char *path, PathSimplifyFlags flags);
|
||||
static inline char* path_simplify(char *path) {
|
||||
return path_simplify_full(path, 0);
|
||||
}
|
||||
|
||||
static inline int path_simplify_alloc(const char *path, char **ret) {
|
||||
assert(ret);
|
||||
|
||||
if (!path) {
|
||||
*ret = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *t = strdup(path);
|
||||
if (!t)
|
||||
return -ENOMEM;
|
||||
|
||||
*ret = path_simplify(t);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline bool path_equal_ptr(const char *a, const char *b) {
|
||||
return !!a == !!b && (!a || path_equal(a, b));
|
||||
}
|
||||
@@ -159,7 +175,7 @@ int fsck_exists_for_fstype(const char *fstype);
|
||||
|
||||
int path_find_first_component(const char **p, bool accept_dot_dot, const char **ret);
|
||||
int path_find_last_component(const char *path, bool accept_dot_dot, const char **next, const char **ret);
|
||||
const char *last_path_component(const char *path);
|
||||
const char* last_path_component(const char *path);
|
||||
int path_extract_filename(const char *path, char **ret);
|
||||
int path_extract_directory(const char *path, char **ret);
|
||||
|
||||
@@ -196,7 +212,7 @@ static inline const char *skip_dev_prefix(const char *p) {
|
||||
}
|
||||
|
||||
bool empty_or_root(const char *path);
|
||||
static inline const char *empty_to_root(const char *path) {
|
||||
static inline const char* empty_to_root(const char *path) {
|
||||
return isempty(path) ? "/" : path;
|
||||
}
|
||||
|
||||
|
||||
+29
-18
@@ -389,15 +389,14 @@ int unit_name_unescape(const char *f, char **ret) {
|
||||
int unit_name_path_escape(const char *f, char **ret) {
|
||||
_cleanup_free_ char *p = NULL;
|
||||
char *s;
|
||||
int r;
|
||||
|
||||
assert(f);
|
||||
assert(ret);
|
||||
|
||||
p = strdup(f);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
|
||||
path_simplify(p);
|
||||
r = path_simplify_alloc(f, &p);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (empty_or_root(p))
|
||||
s = strdup("-");
|
||||
@@ -701,9 +700,15 @@ static bool do_escape_mangle(const char *f, bool allow_globs, char *t) {
|
||||
*
|
||||
* If @allow_globs, globs characters are preserved. Otherwise, they are escaped.
|
||||
*/
|
||||
int unit_name_mangle_with_suffix(const char *name, const char *operation, UnitNameMangle flags, const char *suffix, char **ret) {
|
||||
int unit_name_mangle_with_suffix(
|
||||
const char *name,
|
||||
const char *operation,
|
||||
UnitNameMangle flags,
|
||||
const char *suffix,
|
||||
char **ret) {
|
||||
|
||||
_cleanup_free_ char *s = NULL;
|
||||
bool mangled, suggest_escape = true;
|
||||
bool mangled, suggest_escape = true, warn = flags & UNIT_NAME_MANGLE_WARN;
|
||||
int r;
|
||||
|
||||
assert(name);
|
||||
@@ -724,22 +729,28 @@ int unit_name_mangle_with_suffix(const char *name, const char *operation, UnitNa
|
||||
if (string_is_glob(name) && in_charset(name, VALID_CHARS_GLOB)) {
|
||||
if (flags & UNIT_NAME_MANGLE_GLOB)
|
||||
goto good;
|
||||
log_full(flags & UNIT_NAME_MANGLE_WARN ? LOG_NOTICE : LOG_DEBUG,
|
||||
log_full(warn ? LOG_NOTICE : LOG_DEBUG,
|
||||
"Glob pattern passed%s%s, but globs are not supported for this.",
|
||||
operation ? " " : "", strempty(operation));
|
||||
suggest_escape = false;
|
||||
}
|
||||
|
||||
if (is_device_path(name)) {
|
||||
r = unit_name_from_path(name, ".device", ret);
|
||||
if (r >= 0)
|
||||
return 1;
|
||||
if (r != -EINVAL)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (path_is_absolute(name)) {
|
||||
r = unit_name_from_path(name, ".mount", ret);
|
||||
_cleanup_free_ char *n = NULL;
|
||||
|
||||
r = path_simplify_alloc(name, &n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (is_device_path(n)) {
|
||||
r = unit_name_from_path(n, ".device", ret);
|
||||
if (r >= 0)
|
||||
return 1;
|
||||
if (r != -EINVAL)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = unit_name_from_path(n, ".mount", ret);
|
||||
if (r >= 0)
|
||||
return 1;
|
||||
if (r != -EINVAL)
|
||||
@@ -752,7 +763,7 @@ int unit_name_mangle_with_suffix(const char *name, const char *operation, UnitNa
|
||||
|
||||
mangled = do_escape_mangle(name, flags & UNIT_NAME_MANGLE_GLOB, s);
|
||||
if (mangled)
|
||||
log_full(flags & UNIT_NAME_MANGLE_WARN ? LOG_NOTICE : LOG_DEBUG,
|
||||
log_full(warn ? LOG_NOTICE : LOG_DEBUG,
|
||||
"Invalid unit name \"%s\" escaped as \"%s\"%s.",
|
||||
name, s,
|
||||
suggest_escape ? " (maybe you should use systemd-escape?)" : "");
|
||||
|
||||
+2
-14
@@ -589,7 +589,6 @@ int getgroups_alloc(gid_t** gids) {
|
||||
int get_home_dir(char **ret) {
|
||||
struct passwd *p;
|
||||
const char *e;
|
||||
char *h;
|
||||
uid_t u;
|
||||
|
||||
assert(ret);
|
||||
@@ -622,18 +621,12 @@ int get_home_dir(char **ret) {
|
||||
return -EINVAL;
|
||||
|
||||
found:
|
||||
h = strdup(e);
|
||||
if (!h)
|
||||
return -ENOMEM;
|
||||
|
||||
*ret = path_simplify(h);
|
||||
return 0;
|
||||
return path_simplify_alloc(e, ret);
|
||||
}
|
||||
|
||||
int get_shell(char **ret) {
|
||||
struct passwd *p;
|
||||
const char *e;
|
||||
char *s;
|
||||
uid_t u;
|
||||
|
||||
assert(ret);
|
||||
@@ -665,12 +658,7 @@ int get_shell(char **ret) {
|
||||
return -EINVAL;
|
||||
|
||||
found:
|
||||
s = strdup(e);
|
||||
if (!s)
|
||||
return -ENOMEM;
|
||||
|
||||
*ret = path_simplify(s);
|
||||
return 0;
|
||||
return path_simplify_alloc(e, ret);
|
||||
}
|
||||
|
||||
int reset_uid_gid(void) {
|
||||
|
||||
Reference in New Issue
Block a user