summaryrefslogtreecommitdiff
path: root/src/test/test-stat-util.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2018-06-29 15:57:49 +0200
committerLennart Poettering <lennart@poettering.net>2018-11-29 20:21:39 +0100
commit846b3bd61e1d575b0b28f73c4d15385f94bb1662 (patch)
tree6c5a149cf229086e30ee76a0c9d0a55f67ea8e3a /src/test/test-stat-util.c
parent8e8b5d2e6d91180a57844b09cdbdcbc1fa466bfa (diff)
downloadsystemd-846b3bd61e1d575b0b28f73c4d15385f94bb1662.tar.gz
stat-util: add new APIs device_path_make_{major_minor|canonical}() and device_path_parse_major_minor()
device_path_make_{major_minor|canonical) generate device node paths given a mode_t and a dev_t. We have similar code all over the place, let's unify this in one place. The former will generate a "/dev/char/" or "/dev/block" path, and never go to disk. The latter then goes to disk and resolves that path to the actual path of the device node. device_path_parse_major_minor() reverses device_path_make_major_minor(), also withozut going to disk. We have similar code doing something like this at various places, let's unify this in a single set of functions. This also allows us to teach them special tricks, for example handling of the /run/systemd/inaccessible/{blk|chr} device nodes, which we use for masking device nodes, and which do not exist in /dev/char/* and /dev/block/*
Diffstat (limited to 'src/test/test-stat-util.c')
-rw-r--r--src/test/test-stat-util.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/src/test/test-stat-util.c b/src/test/test-stat-util.c
index 713fbc9a08..4201edac97 100644
--- a/src/test/test-stat-util.c
+++ b/src/test/test-stat-util.c
@@ -11,6 +11,7 @@
#include "missing.h"
#include "mount-util.h"
#include "stat-util.h"
+#include "path-util.h"
static void test_files_same(void) {
_cleanup_close_ int fd = -1;
@@ -116,6 +117,44 @@ static void test_device_major_minor_valid(void) {
assert_se(DEVICE_MINOR_VALID(minor(0)));
}
+static void test_device_path_make_canonical_one(const char *path) {
+ _cleanup_free_ char *resolved = NULL, *raw = NULL;
+ struct stat st;
+ dev_t devno;
+ mode_t mode;
+ int r;
+
+ assert_se(stat(path, &st) >= 0);
+ r = device_path_make_canonical(st.st_mode, st.st_rdev, &resolved);
+ if (r == -ENOENT) /* maybe /dev/char/x:y and /dev/block/x:y are missing in this test environment, because we
+ * run in a container or so? */
+ return;
+
+ assert_se(r >= 0);
+ assert_se(path_equal(path, resolved));
+
+ assert_se(device_path_make_major_minor(st.st_mode, st.st_rdev, &raw) >= 0);
+ assert_se(device_path_parse_major_minor(raw, &mode, &devno) >= 0);
+
+ assert_se(st.st_rdev == devno);
+ assert_se((st.st_mode & S_IFMT) == (mode & S_IFMT));
+}
+
+static void test_device_path_make_canonical(void) {
+
+ test_device_path_make_canonical_one("/dev/null");
+ test_device_path_make_canonical_one("/dev/zero");
+ test_device_path_make_canonical_one("/dev/full");
+ test_device_path_make_canonical_one("/dev/random");
+ test_device_path_make_canonical_one("/dev/urandom");
+ test_device_path_make_canonical_one("/dev/tty");
+
+ if (is_device_node("/run/systemd/inaccessible/chr") > 0) {
+ test_device_path_make_canonical_one("/run/systemd/inaccessible/chr");
+ test_device_path_make_canonical_one("/run/systemd/inaccessible/blk");
+ }
+}
+
int main(int argc, char *argv[]) {
test_files_same();
test_is_symlink();
@@ -123,6 +162,7 @@ int main(int argc, char *argv[]) {
test_path_is_temporary_fs();
test_fd_is_network_ns();
test_device_major_minor_valid();
+ test_device_path_make_canonical();
return 0;
}