From: Yu Watanabe Date: Sun, 18 Sep 2022 22:04:37 +0000 (+0900) Subject: sd-device: re-implement device_sysattrs_read_all() without recursion X-Git-Tag: v252-rc1~142^2~5 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4bc9d8165b57b23a2d70f66141cff6877256a613;p=thirdparty%2Fsystemd.git sd-device: re-implement device_sysattrs_read_all() without recursion --- diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c index 96a8ebf6b8e..fd2bc193234 100644 --- a/src/libsystemd/sd-device/sd-device.c +++ b/src/libsystemd/sd-device/sd-device.c @@ -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;