summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2016-12-08 17:19:27 +0100
committerLennart Poettering <lennart@poettering.net>2016-12-20 20:00:08 +0100
commit7dcdb24e192c664d1e84db748fa38819f3daa693 (patch)
tree58f4714a75fa50090c8150bd4ba9a61b602f9dfa
parent245f1d244b3a91e7cc18ed2d21226292251b934d (diff)
util-lib: beef path_is_os_tree() up a bit
Let's use chase_symlinks() when looking for /etc/os-release and /usr/lib/os-release as these files might be symlinks (and actually are IRL on some distros).
-rw-r--r--src/basic/stat-util.c28
-rw-r--r--src/test/test-stat-util.c7
2 files changed, 25 insertions, 10 deletions
diff --git a/src/basic/stat-util.c b/src/basic/stat-util.c
index 309e84b93d..5663a29cd6 100644
--- a/src/basic/stat-util.c
+++ b/src/basic/stat-util.c
@@ -28,6 +28,7 @@
#include "dirent-util.h"
#include "fd-util.h"
+#include "fs-util.h"
#include "macro.h"
#include "missing.h"
#include "stat-util.h"
@@ -143,22 +144,29 @@ int path_is_read_only_fs(const char *path) {
}
int path_is_os_tree(const char *path) {
- char *p;
int r;
assert(path);
- /* We use /usr/lib/os-release as flag file if something is an OS */
- p = strjoina(path, "/usr/lib/os-release");
- r = access(p, F_OK);
- if (r >= 0)
- return 1;
+ /* Does the path exist at all? If not, generate an error immediately. This is useful so that a missing root dir
+ * always results in -ENOENT, and we can properly distuingish the case where the whole root doesn't exist from
+ * the case where just the os-release file is missing. */
+ if (laccess(path, F_OK) < 0)
+ return -errno;
- /* Also check for the old location in /etc, just in case. */
- p = strjoina(path, "/etc/os-release");
- r = access(p, F_OK);
+ /* We use /usr/lib/os-release as flag file if something is an OS */
+ r = chase_symlinks("/usr/lib/os-release", path, CHASE_PREFIX_ROOT, NULL);
+ if (r == -ENOENT) {
+
+ /* Also check for the old location in /etc, just in case. */
+ r = chase_symlinks("/etc/os-release", path, CHASE_PREFIX_ROOT, NULL);
+ if (r == -ENOENT)
+ return 0; /* We got nothing */
+ }
+ if (r < 0)
+ return r;
- return r >= 0;
+ return 1;
}
int files_same(const char *filea, const char *fileb) {
diff --git a/src/test/test-stat-util.c b/src/test/test-stat-util.c
index 6c34250a01..10fc4af79f 100644
--- a/src/test/test-stat-util.c
+++ b/src/test/test-stat-util.c
@@ -60,9 +60,16 @@ static void test_is_symlink(void) {
unlink(name_link);
}
+static void test_path_is_os_tree(void) {
+ assert_se(path_is_os_tree("/") > 0);
+ assert_se(path_is_os_tree("/etc") == 0);
+ assert_se(path_is_os_tree("/idontexist") == -ENOENT);
+}
+
int main(int argc, char *argv[]) {
test_files_same();
test_is_symlink();
+ test_path_is_os_tree();
return 0;
}