config: 加载用户配置动态链接库

This commit is contained in:
2026-03-23 14:51:26 +08:00
parent fb3bb10eab
commit 32679b354a
2 changed files with 114 additions and 0 deletions

102
src/config/loader.c Normal file
View File

@@ -0,0 +1,102 @@
#include "config/loader.h"
#include <dlfcn.h>
#include <stdlib.h>
#include <unistd.h>
#include "utils.h"
static char *config_loader_join_path(const char *base, const char *suffix) {
if (!base || !suffix) return nullptr;
size_t base_len = strlen(base);
size_t suffix_len = strlen(suffix);
char *path = p_new(char, base_len + suffix_len + 1);
memcpy(path, base, base_len);
memcpy(path + base_len, suffix, suffix_len + 1);
return path;
}
static bool config_loader_resolve_path(char **out_path, bool *out_is_explicit,
const char *override_path) {
const char *path = override_path;
if (path && *path) {
*out_path = p_strdup(path);
*out_is_explicit = true;
return true;
}
path = getenv("ZDWM_CONFIG_LIB");
if (path && *path) {
*out_path = p_strdup(path);
*out_is_explicit = true;
return true;
}
path = getenv("XDG_CONFIG_HOME");
if (path && *path) {
*out_path = config_loader_join_path(path, "/zdwm/config.so");
*out_is_explicit = false;
return *out_path != nullptr;
}
path = getenv("HOME");
if (path && *path) {
*out_path = config_loader_join_path(path, "/.config/zdwm/config.so");
*out_is_explicit = false;
return *out_path != nullptr;
}
return false;
}
bool config_loader_load(config_loader_t *loader, const char *override_path) {
if (!loader) return false;
config_loader_cleanup(loader);
char *path = nullptr;
bool is_explicit = false;
if (!config_loader_resolve_path(&path, &is_explicit, override_path)) {
return false;
}
loader->path = path;
if (access(path, F_OK) != 0) {
if (is_explicit) {
warn("config library not found: %s", path);
config_loader_cleanup(loader);
return false;
}
return true;
}
loader->handle = dlopen(path, RTLD_NOW | RTLD_LOCAL);
if (!loader->handle) {
warn("failed to load config library %s: %s", path, dlerror());
config_loader_cleanup(loader);
return false;
}
dlerror();
loader->setup = (zdwm_config_setup_fn *)dlsym(loader->handle, "setup");
const char *error = dlerror();
if (error) {
warn("failed to resolve setup from %s: %s", path, error);
config_loader_cleanup(loader);
return false;
}
return true;
}
void config_loader_cleanup(config_loader_t *loader) {
if (!loader) return;
loader->setup = nullptr;
if (loader->handle) dlclose(loader->handle);
loader->handle = nullptr;
p_delete(&loader->path);
}

12
src/config/loader.h Normal file
View File

@@ -0,0 +1,12 @@
#pragma once
#include <zdwm/config.h>
typedef struct config_loader_t {
char *path;
void *handle;
zdwm_config_setup_fn *setup;
} config_loader_t;
bool config_loader_load(config_loader_t *loader, const char *override_path);
void config_loader_cleanup(config_loader_t *loader);