This is not a comprehensive port, but mostly some low-hanging fruit.
}
int xdg_user_config_dir(char **ret, const char *suffix) {
+ _cleanup_free_ char *j = NULL;
const char *e;
- char *j;
int r;
assert(ret);
e = getenv("XDG_CONFIG_HOME");
- if (e)
+ if (e) {
j = path_join(e, suffix);
- else {
- _cleanup_free_ char *home = NULL;
-
- r = get_home_dir(&home);
+ if (!j)
+ return -ENOMEM;
+ } else {
+ r = get_home_dir(&j);
if (r < 0)
return r;
- j = path_join(home, "/.config", suffix);
+ if (!path_extend(&j, "/.config", suffix))
+ return -ENOMEM;
}
- if (!j)
- return -ENOMEM;
-
- *ret = j;
+ *ret = TAKE_PTR(j);
return 0;
}
int xdg_user_data_dir(char **ret, const char *suffix) {
+ _cleanup_free_ char *j = NULL;
const char *e;
- char *j;
int r;
assert(ret);
* /etc/systemd/ anyway. */
e = getenv("XDG_DATA_HOME");
- if (e)
+ if (e) {
j = path_join(e, suffix);
- else {
- _cleanup_free_ char *home = NULL;
-
- r = get_home_dir(&home);
+ if (!j)
+ return -ENOMEM;
+ } else {
+ r = get_home_dir(&j);
if (r < 0)
return r;
- j = path_join(home, "/.local/share", suffix);
+ if (!path_extend(&j, "/.local/share", suffix))
+ return -ENOMEM;
}
- if (!j)
- return -ENOMEM;
- *ret = j;
+ *ret = TAKE_PTR(j);
return 1;
}
/* Resolve a single-component name to a full path */
for (;;) {
- _cleanup_free_ char *j = NULL, *element = NULL;
+ _cleanup_free_ char *element = NULL;
_cleanup_close_ int fd = -1;
r = extract_first_word(&p, &element, ":", EXTRACT_RELAX|EXTRACT_DONT_COALESCE_SEPARATORS);
if (!path_is_absolute(element))
continue;
- j = path_join(element, name);
- if (!j)
+ if (!path_extend(&element, name))
return -ENOMEM;
- r = check_x_access(j, ret_fd ? &fd : NULL);
+ r = check_x_access(element, ret_fd ? &fd : NULL);
if (r < 0) {
/* PATH entries which we don't have access to are ignored, as per tradition. */
if (r != -EACCES)
/* Found it! */
if (ret_filename)
- *ret_filename = path_simplify(TAKE_PTR(j), false);
+ *ret_filename = path_simplify(TAKE_PTR(element), false);
if (ret_fd)
*ret_fd = TAKE_FD(fd);
return 0;
if (!path_is_absolute(path)) {
- _cleanup_free_ char *p = NULL;
-
if (dirfd == AT_FDCWD)
- r = safe_getcwd(&p);
+ r = safe_getcwd(&abspath);
else
- r = fd_get_path(dirfd, &p);
+ r = fd_get_path(dirfd, &abspath);
if (r < 0)
return r;
- path = abspath = path_join(p, path);
- if (!path)
+ if (!path_extend(&abspath, path))
return -ENOMEM;
+
+ path = abspath;
}
return selinux_create_file_prepare_abspath(path, mode);
return -EINVAL;
if (d) {
- char *j;
-
- j = path_join(d, nf);
- if (!j)
+ if (!path_extend(&d, nf))
return -ENOMEM;
- *ret = path_simplify(j, false);
+ *ret = path_simplify(TAKE_PTR(d), false);
} else
*ret = TAKE_PTR(nf);
return -EINVAL;
if (d) {
- char *j;
-
- j = path_join(d, nf);
- if (!j)
+ if (!path_extend(&d, nf))
return -ENOMEM;
- *ret = path_simplify(j, false);
+ *ret = path_simplify(TAKE_PTR(d), false);
} else
*ret = TAKE_PTR(nf);
goto fail;
if (exec_directory_is_private(context, type)) {
- _cleanup_free_ char *private_root = NULL;
-
/* So, here's one extra complication when dealing with DynamicUser=1 units. In that
* case we want to avoid leaving a directory around fully accessible that is owned by
* a dynamic user whose UID is later on reused. To lock this down we use the same
* Also, note that we don't do this for EXEC_DIRECTORY_RUNTIME as that's often used
* for sharing files or sockets with other services. */
- private_root = path_join(params->prefix[type], "private");
- if (!private_root) {
+ pp = path_join(params->prefix[type], "private");
+ if (!pp) {
r = -ENOMEM;
goto fail;
}
/* First set up private root if it doesn't exist yet, with access mode 0700 and owned by root:root */
- r = mkdir_safe_label(private_root, 0700, 0, 0, MKDIR_WARN_MODE);
+ r = mkdir_safe_label(pp, 0700, 0, 0, MKDIR_WARN_MODE);
if (r < 0)
goto fail;
- pp = path_join(private_root, *rt);
- if (!pp) {
+ if (!path_extend(&pp, *rt)) {
r = -ENOMEM;
goto fail;
}
static int from_home_dir(const char *envname, const char *suffix, char **buffer, const char **ret) {
_cleanup_free_ char *h = NULL;
- char *cc = NULL;
int r;
assert(suffix);
if (r < 0)
return r;
- cc = path_join(h, suffix);
- if (!cc)
+ if (!path_extend(&h, suffix))
return -ENOMEM;
- *buffer = cc;
- *ret = cc;
+ *buffer = h;
+ *ret = TAKE_PTR(h);
return 0;
}
/* Three syntaxes permitted: relative to $HOME, $HOME itself, and absolute path */
if (startswith(p, "$HOME/")) {
_cleanup_free_ char *h = NULL;
- char *cc;
r = get_home_dir(&h);
if (r < 0)
return r;
- cc = path_join(h, p+5);
- if (!cc)
+ if (!path_extend(&h, p+5))
return -ENOMEM;
- *buffer = cc;
- *ret = cc;
+ *buffer = h;
+ *ret = TAKE_PTR(h);
return 0;
} else if (streq(p, "$HOME")) {
/* The desktop directory defaults to $HOME/Desktop, the others to $HOME */
if (streq(field, "XDG_DESKTOP_DIR")) {
_cleanup_free_ char *h = NULL;
- char *cc;
r = get_home_dir(&h);
if (r < 0)
return r;
- cc = path_join(h, "Desktop");
- if (!cc)
+ if (!path_extend(&h, "Desktop"))
return -ENOMEM;
- *buffer = cc;
- *ret = cc;
+ *buffer = h;
+ *ret = TAKE_PTR(h);
} else {
-
r = get_home_dir(buffer);
if (r < 0)
return r;