]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-device: introduce devpath_from_devnum()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 27 Aug 2022 17:45:56 +0000 (02:45 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 28 Aug 2022 00:08:21 +0000 (09:08 +0900)
src/libsystemd/meson.build
src/libsystemd/sd-device/device-private.h
src/libsystemd/sd-device/device-util.c [new file with mode: 0644]
src/libsystemd/sd-device/device-util.h
src/libsystemd/sd-device/sd-device.c
src/libsystemd/sd-device/test-sd-device.c

index 7f10e87d6c1d6a7fd6a50f5ff1a1beefc9baddcd..9238e32980613e41e44e3e0fc4816bad26aa1cd7 100644 (file)
@@ -128,6 +128,7 @@ libsystemd_sources = files(
         'sd-device/device-monitor.c',
         'sd-device/device-private.c',
         'sd-device/device-private.h',
+        'sd-device/device-util.c',
         'sd-device/device-util.h',
         'sd-device/sd-device.c',
         'sd-hwdb/hwdb-internal.h',
index d993b77b49c8b3341feddb21e636f13b12b26102..d33cddcf80f0350f06e015d138f7d9aeb031d31d 100644 (file)
@@ -10,6 +10,7 @@
 
 #include "macro.h"
 
+int device_new_from_mode_and_devnum(sd_device **ret, mode_t mode, dev_t devnum);
 int device_new_from_nulstr(sd_device **ret, char *nulstr, size_t len);
 int device_new_from_strv(sd_device **ret, char **strv);
 int device_new_from_watch_handle_at(sd_device **ret, int dirfd, int wd);
diff --git a/src/libsystemd/sd-device/device-util.c b/src/libsystemd/sd-device/device-util.c
new file mode 100644 (file)
index 0000000..f1cd67a
--- /dev/null
@@ -0,0 +1,33 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "device-private.h"
+#include "device-util.h"
+#include "devnum-util.h"
+#include "string-util.h"
+
+int devpath_from_devnum(mode_t mode, dev_t devnum, char **ret) {
+        _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
+        _cleanup_free_ char *s = NULL;
+        const char *devname;
+        int r;
+
+        assert(ret);
+
+        if (major(devnum) == 0 && minor(devnum) == 0)
+                return device_path_make_inaccessible(mode, ret);
+
+        r = device_new_from_mode_and_devnum(&dev, mode, devnum);
+        if (r < 0)
+                return r;
+
+        r = sd_device_get_devname(dev, &devname);
+        if (r < 0)
+                return r;
+
+        s = strdup(devname);
+        if (!s)
+                return -ENOMEM;
+
+        *ret = TAKE_PTR(s);
+        return 0;
+}
index d92cbd6cc7411b659b9c995240614791383b06bb..6150c45082c82660b8740879490951ef58570361 100644 (file)
@@ -2,6 +2,7 @@
 #pragma once
 
 #include <stdbool.h>
+#include <sys/types.h>
 
 #include "sd-device.h"
 
@@ -79,3 +80,5 @@
 #define log_device_notice_errno(device, error, ...)  log_device_full_errno(device, LOG_NOTICE, error, __VA_ARGS__)
 #define log_device_warning_errno(device, error, ...) log_device_full_errno(device, LOG_WARNING, error, __VA_ARGS__)
 #define log_device_error_errno(device, error, ...)   log_device_full_errno(device, LOG_ERR, error, __VA_ARGS__)
+
+int devpath_from_devnum(mode_t mode, dev_t devnum, char **ret);
index 51bee24d511f3bc2c9eac2b10d5a7755d7955d7c..26b9e51c937ddbf2b323801b5c0cb53961bd77a9 100644 (file)
@@ -279,7 +279,7 @@ _public_ int sd_device_new_from_syspath(sd_device **ret, const char *syspath) {
         return device_new_from_syspath(ret, syspath, /* strict = */ true);
 }
 
-static int device_new_from_mode_and_devnum(sd_device **ret, mode_t mode, dev_t devnum) {
+int device_new_from_mode_and_devnum(sd_device **ret, mode_t mode, dev_t devnum) {
         _cleanup_(sd_device_unrefp) sd_device *dev = NULL;
         _cleanup_free_ char *syspath = NULL;
         const char *t, *subsystem;
index 66c8d70faa9da603b93f31e1f9d22bfa95e71680..74fdd7b600956c07dfcc741886b15b7d8c66c302 100644 (file)
@@ -14,6 +14,7 @@
 #include "nulstr-util.h"
 #include "path-util.h"
 #include "rm-rf.h"
+#include "stat-util.h"
 #include "string-util.h"
 #include "tests.h"
 #include "time-util.h"
@@ -499,4 +500,34 @@ TEST(sd_device_new_from_path) {
         }
 }
 
+static void test_devpath_from_devnum_one(const char *path) {
+        _cleanup_free_ char *resolved = NULL;
+        struct stat st;
+
+        log_debug("> %s", path);
+
+        if (stat(path, &st) < 0) {
+                assert_se(errno == ENOENT);
+                log_notice("Path %s not found, skipping test", path);
+                return;
+        }
+
+        assert_se(devpath_from_devnum(st.st_mode, st.st_rdev, &resolved) >= 0);
+        assert_se(path_equal(path, resolved));
+}
+
+TEST(devpath_from_devnum) {
+        test_devpath_from_devnum_one("/dev/null");
+        test_devpath_from_devnum_one("/dev/zero");
+        test_devpath_from_devnum_one("/dev/full");
+        test_devpath_from_devnum_one("/dev/random");
+        test_devpath_from_devnum_one("/dev/urandom");
+        test_devpath_from_devnum_one("/dev/tty");
+
+        if (is_device_node("/run/systemd/inaccessible/blk") > 0) {
+                test_devpath_from_devnum_one("/run/systemd/inaccessible/chr");
+                test_devpath_from_devnum_one("/run/systemd/inaccessible/blk");
+        }
+}
+
 DEFINE_TEST_MAIN(LOG_INFO);