diff options
author | Lennart Poettering <lennart@poettering.net> | 2023-01-23 16:34:07 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2023-01-24 18:13:27 +0100 |
commit | 162f6477c60bf53da242276dee1efe03c686c9f3 (patch) | |
tree | ac0bd8c16e7b193e5e834e8ea3c7104f5c552efa /src/basic/path-util.c | |
parent | bootctl-uki: several coding style fixlets (diff) | |
download | systemd-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.c | 38 |
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) { |