]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-device: re-implement device_sysattrs_read_all() without recursion
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 18 Sep 2022 22:04:37 +0000 (07:04 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 19 Sep 2022 09:04:13 +0000 (18:04 +0900)
src/libsystemd/sd-device/sd-device.c

index 96a8ebf6b8e95d4939ca9e7f1b62cdb34f29fd63..fd2bc1932342a8e70e073f010e4f8584a15fe08b 100644 (file)
@@ -1866,12 +1866,15 @@ _public_ const char *sd_device_get_property_next(sd_device *device, const char *
         return key;
 }
 
-static int device_sysattrs_read_all_internal(sd_device *device, const char *subdir) {
+static int device_sysattrs_read_all_internal(sd_device *device, const char *subdir, Set **stack) {
         _cleanup_free_ char *path_dir = NULL;
         _cleanup_closedir_ DIR *dir = NULL;
         const char *syspath;
         int r;
 
+        assert(device);
+        assert(stack);
+
         r = sd_device_get_syspath(device, &syspath);
         if (r < 0)
                 return r;
@@ -1919,8 +1922,11 @@ static int device_sysattrs_read_all_internal(sd_device *device, const char *subd
                 }
 
                 if (de->d_type == DT_DIR) {
-                        /* read subdirectory */
-                        r = device_sysattrs_read_all_internal(device, p ?: de->d_name);
+                        /* push the sub-directory into the stack, and read it later. */
+                        if (p)
+                                r = set_ensure_consume(stack, &path_hash_ops_free, TAKE_PTR(p));
+                        else
+                                r = set_put_strdup_full(stack, &path_hash_ops_free, de->d_name);
                         if (r < 0)
                                 return r;
 
@@ -1945,6 +1951,7 @@ static int device_sysattrs_read_all_internal(sd_device *device, const char *subd
 }
 
 static int device_sysattrs_read_all(sd_device *device) {
+        _cleanup_set_free_ Set *stack = NULL;
         int r;
 
         assert(device);
@@ -1952,10 +1959,22 @@ static int device_sysattrs_read_all(sd_device *device) {
         if (device->sysattrs_read)
                 return 0;
 
-        r = device_sysattrs_read_all_internal(device, NULL);
+        r = device_sysattrs_read_all_internal(device, NULL, &stack);
         if (r < 0)
                 return r;
 
+        for (;;) {
+                _cleanup_free_ char *subdir = NULL;
+
+                subdir = set_steal_first(stack);
+                if (!subdir)
+                        break;
+
+                r = device_sysattrs_read_all_internal(device, subdir, &stack);
+                if (r < 0)
+                        return r;
+        }
+
         device->sysattrs_read = true;
 
         return 0;