SOL_API int sol_util_iterate_dir(const char *path, enum sol_util_iterate_dir_reason (*iterate_dir_cb)(void *data, const char *dir_path, struct dirent *ent), const void *data) { DIR *dir; struct dirent *ent, *res; int r; long name_max; size_t len; SOL_NULL_CHECK(path, -EINVAL); SOL_NULL_CHECK(iterate_dir_cb, -EINVAL); /* See readdir_r(3) */ name_max = pathconf(path, _PC_NAME_MAX); if (name_max == -1) name_max = 255; len = offsetof(struct dirent, d_name) + name_max + 1; ent = malloc(len); SOL_NULL_CHECK(ent, -ENOMEM); dir = opendir(path); if (!dir) { int aux_errno = errno; SOL_INF("Could not open dir [%s] to iterate: %s", path, sol_util_strerrora(aux_errno)); free(ent); return -aux_errno; } r = readdir_r(dir, ent, &res); SOL_INT_CHECK_GOTO(r, != 0, exit); while (res) { if (!streq(res->d_name, ".") && !streq(res->d_name, "..")) { r = iterate_dir_cb((void *)data, path, res); SOL_INT_CHECK_GOTO(r, < 0, exit); if (r == SOL_UTIL_ITERATE_DIR_STOP) break; } r = readdir_r(dir, ent, &res); SOL_INT_CHECK_GOTO(r, != 0, exit); }
bool sol_util_iterate_dir(const char *path, bool (*iterate_dir_cb)(void *data, const char *dir_path, struct dirent *ent), const void *data) { DIR *dir; struct dirent *ent, *res; int success; long name_max; size_t len; bool result = false; SOL_NULL_CHECK(path, false); SOL_NULL_CHECK(iterate_dir_cb, false); /* See readdir_r(3) */ name_max = pathconf(path, _PC_NAME_MAX); if (name_max == -1) name_max = 255; len = offsetof(struct dirent, d_name) + name_max + 1; ent = malloc(len); SOL_NULL_CHECK(ent, false); dir = opendir(path); if (!dir) { SOL_INF("Could not open dir [%s] to iterate: %s", path, sol_util_strerrora(errno)); free(ent); return false; } success = readdir_r(dir, ent, &res); while (success == 0 && res) { if (iterate_dir_cb((void *)data, path, res)) { result = true; break; } success = readdir_r(dir, ent, &res); } free(ent); closedir(dir); return result; }