]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-device: introduce sd_device_new_from_devname()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 27 Mar 2022 14:38:36 +0000 (23:38 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 1 Apr 2022 06:03:33 +0000 (15:03 +0900)
and sd_device_new_from_path() which takes devname or syspath.

src/libsystemd/libsystemd.sym
src/libsystemd/sd-device/sd-device.c
src/systemd/sd-device.h

index 2773d28b4bb4bbcd8bfe2b0c9ae18f33cbf7c6a6..0066894d547cff8dbae51b689eff386f159bbcff 100644 (file)
@@ -773,4 +773,6 @@ global:
 LIBSYSTEMD_251 {
 global:
         sd_id128_to_uuid_string;
+        sd_device_new_from_devname;
+        sd_device_new_from_path;
 } LIBSYSTEMD_250;
index 19bf01abc718f1b0df0a5867fbc6fe7aea7b3dff..c7389c8a3b5bd9daaf78c6ec43fc25623968d72b 100644 (file)
@@ -415,6 +415,46 @@ _public_ int sd_device_new_from_stat_rdev(sd_device **ret, const struct stat *st
         return sd_device_new_from_devnum(ret, type, st->st_rdev);
 }
 
+_public_ int sd_device_new_from_devname(sd_device **ret, const char *devname) {
+        struct stat st;
+
+        assert_return(ret, -EINVAL);
+        assert_return(devname, -EINVAL);
+
+        /* This function actually accepts both devlinks and devnames, i.e. both symlinks and device
+         * nodes below /dev/. */
+
+        /* Also ignore when the specified path is "/dev". */
+        if (isempty(path_startswith(devname, "/dev")))
+                return -EINVAL;
+
+        if (device_path_parse_major_minor(devname, NULL, NULL) >= 0) {
+                _cleanup_free_ char *syspath = NULL;
+
+                /* Let's shortcut when "/dev/block/maj:min" or "/dev/char/maj:min" is specified.
+                 * In that case, we directly convert the path to syspath, hence it is not necessary
+                 * that the specified path exists. So, this works fine without udevd being running. */
+
+                syspath = path_join("/sys", devname);
+                return sd_device_new_from_syspath(ret, syspath);
+        }
+
+        if (stat(devname, &st) < 0)
+                return ERRNO_IS_DEVICE_ABSENT(errno) ? -ENODEV : -errno;
+
+        return sd_device_new_from_stat_rdev(ret, &st);
+}
+
+_public_ int sd_device_new_from_path(sd_device **ret, const char *path) {
+        assert_return(ret, -EINVAL);
+        assert_return(path, -EINVAL);
+
+        if (path_startswith(path, "/dev"))
+                return sd_device_new_from_devname(ret, path);
+
+        return sd_device_new_from_syspath(ret, path);
+}
+
 int device_set_devtype(sd_device *device, const char *devtype) {
         _cleanup_free_ char *t = NULL;
         int r;
index 189a110ea0d1631c9a374f2f96e8a4fc27919a08..2ac670b08cd78723821c553e25f837ef717fe968 100644 (file)
@@ -62,6 +62,8 @@ int sd_device_new_from_devnum(sd_device **ret, char type, dev_t devnum);
 int sd_device_new_from_subsystem_sysname(sd_device **ret, const char *subsystem, const char *sysname);
 int sd_device_new_from_device_id(sd_device **ret, const char *id);
 int sd_device_new_from_stat_rdev(sd_device **ret, const struct stat *st);
+int sd_device_new_from_devname(sd_device **ret, const char *devname);
+int sd_device_new_from_path(sd_device **ret, const char *path);
 int sd_device_new_from_ifname(sd_device **ret, const char *ifname);
 int sd_device_new_from_ifindex(sd_device **ret, int ifindex);