summaryrefslogtreecommitdiffstats
path: root/src/basic/path-util.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2023-01-23 16:34:07 +0100
committerLennart Poettering <lennart@poettering.net>2023-01-24 18:13:27 +0100
commit162f6477c60bf53da242276dee1efe03c686c9f3 (patch)
treeac0bd8c16e7b193e5e834e8ea3c7104f5c552efa /src/basic/path-util.c
parentbootctl-uki: several coding style fixlets (diff)
downloadsystemd-162f6477c60bf53da242276dee1efe03c686c9f3.tar.xz
systemd-162f6477c60bf53da242276dee1efe03c686c9f3.zip
path-util: rework file_in_same_dir() on top of path_extract_directory()
Let's port one more over. Note that this changes behaviour of file_in_same_dir() in some regards. Specifically, a trailing slash of the input path will be treated differently: previously we'd operate below that dir then, instead of the parent. I think that makes little sense however, and I think the code using this function doesn't expect that either. Moroever, addresses some corner cases if the path is specified as "/" or ".", i.e. where e cannot extract a parent. These will now be treated as error, which I think is much cleaner.
Diffstat (limited to 'src/basic/path-util.c')
-rw-r--r--src/basic/path-util.c38
1 files changed, 21 insertions, 17 deletions
diff --git a/src/basic/path-util.c b/src/basic/path-util.c
index cc45cb311e..b442eebb87 100644
--- a/src/basic/path-util.c
+++ b/src/basic/path-util.c
@@ -1164,31 +1164,35 @@ bool path_is_normalized(const char *p) {
return true;
}
-char *file_in_same_dir(const char *path, const char *filename) {
- char *e, *ret;
- size_t k;
+int file_in_same_dir(const char *path, const char *filename, char **ret) {
+ _cleanup_free_ char *b = NULL;
+ int r;
assert(path);
assert(filename);
+ assert(ret);
- /* This removes the last component of path and appends
- * filename, unless the latter is absolute anyway or the
- * former isn't */
+ /* This removes the last component of path and appends filename, unless the latter is absolute anyway
+ * or the former isn't */
if (path_is_absolute(filename))
- return strdup(filename);
-
- e = strrchr(path, '/');
- if (!e)
- return strdup(filename);
+ b = strdup(filename);
+ else {
+ _cleanup_free_ char *dn = NULL;
- k = strlen(filename);
- ret = new(char, (e + 1 - path) + k + 1);
- if (!ret)
- return NULL;
+ r = path_extract_directory(path, &dn);
+ if (r == -EDESTADDRREQ) /* no path prefix */
+ b = strdup(filename);
+ else if (r < 0)
+ return r;
+ else
+ b = path_join(dn, filename);
+ }
+ if (!b)
+ return -ENOMEM;
- memcpy(mempcpy(ret, path, e + 1 - path), filename, k + 1);
- return ret;
+ *ret = TAKE_PTR(b);
+ return 0;
}
bool hidden_or_backup_file(const char *filename) {