mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-04 13:30:12 -05:00
conf: Load and stack all config files.
Load and parse config files in the following order: $PIPEWIRE_CONFIG_DIR or /usr/share/pipewire /etc/pipewire $XDG_CONFIG_DIR or ~/.config/pipewire This ensure we always load a working base config and reduce the chances of failing because of a back user config file. The user config file now only needs to contain the section that needs the be changed. See #207
This commit is contained in:
parent
d09df66aec
commit
db44fe47ee
1 changed files with 98 additions and 78 deletions
|
|
@ -64,11 +64,15 @@ static int make_path(char *path, int size, const char *paths[])
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_read_path(char *path, size_t size, const char *prefix, const char *name)
|
static int get_read_path(char *path, size_t size, const char *prefix, const char *name,
|
||||||
|
bool useronly, uint32_t *state)
|
||||||
{
|
{
|
||||||
const char *dir;
|
const char *dir;
|
||||||
char buffer[4096];
|
char buffer[4096];
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
switch ((*state)++) {
|
||||||
|
case 0:
|
||||||
if (prefix[0] == '/') {
|
if (prefix[0] == '/') {
|
||||||
const char *paths[] = { prefix, name, NULL };
|
const char *paths[] = { prefix, name, NULL };
|
||||||
if (make_path(path, size, paths) == 0 &&
|
if (make_path(path, size, paths) == 0 &&
|
||||||
|
|
@ -76,9 +80,10 @@ static int get_read_path(char *path, size_t size, const char *prefix, const char
|
||||||
return 1;
|
return 1;
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
if (pw_check_option("no-config", "true"))
|
break;
|
||||||
goto no_config;
|
case 1:
|
||||||
|
if (useronly)
|
||||||
|
break;
|
||||||
dir = getenv("PIPEWIRE_CONFIG_DIR");
|
dir = getenv("PIPEWIRE_CONFIG_DIR");
|
||||||
if (dir != NULL) {
|
if (dir != NULL) {
|
||||||
const char *paths[] = { dir, prefix, name, NULL };
|
const char *paths[] = { dir, prefix, name, NULL };
|
||||||
|
|
@ -86,7 +91,28 @@ static int get_read_path(char *path, size_t size, const char *prefix, const char
|
||||||
access(path, R_OK) == 0)
|
access(path, R_OK) == 0)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
dir = PIPEWIRE_CONFDATADIR;
|
||||||
|
if (dir != NULL) {
|
||||||
|
const char *paths[] = { dir, prefix, name, NULL };
|
||||||
|
if (make_path(path, size, paths) == 0 &&
|
||||||
|
access(path, R_OK) == 0)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (pw_check_option("no-config", "true"))
|
||||||
|
return 0;
|
||||||
|
if (useronly)
|
||||||
|
break;
|
||||||
|
dir = PIPEWIRE_CONFIG_DIR;
|
||||||
|
if (dir != NULL) {
|
||||||
|
const char *paths[] = { dir, prefix, name, NULL };
|
||||||
|
if (make_path(path, size, paths) == 0 &&
|
||||||
|
access(path, R_OK) == 0)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
dir = getenv("XDG_CONFIG_HOME");
|
dir = getenv("XDG_CONFIG_HOME");
|
||||||
if (dir != NULL) {
|
if (dir != NULL) {
|
||||||
const char *paths[] = { dir, "pipewire", prefix, name, NULL };
|
const char *paths[] = { dir, "pipewire", prefix, name, NULL };
|
||||||
|
|
@ -106,21 +132,10 @@ static int get_read_path(char *path, size_t size, const char *prefix, const char
|
||||||
access(path, R_OK) == 0)
|
access(path, R_OK) == 0)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
dir = PIPEWIRE_CONFIG_DIR;
|
default:
|
||||||
if (dir != NULL) {
|
return 0;
|
||||||
const char *paths[] = { dir, prefix, name, NULL };
|
|
||||||
if (make_path(path, size, paths) == 0 &&
|
|
||||||
access(path, R_OK) == 0)
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
no_config:
|
|
||||||
dir = PIPEWIRE_CONFDATADIR;
|
|
||||||
if (dir != NULL) {
|
|
||||||
const char *paths[] = { dir, prefix, name, NULL };
|
|
||||||
if (make_path(path, size, paths) == 0 &&
|
|
||||||
access(path, R_OK) == 0)
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -242,53 +257,58 @@ error:
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int conf_load(const char *prefix, const char *name, struct pw_properties *conf)
|
static int conf_load(const char *prefix, const char *name, bool useronly, struct pw_properties *conf)
|
||||||
{
|
{
|
||||||
char path[PATH_MAX], *data;
|
char path[PATH_MAX], *data;
|
||||||
struct stat sbuf;
|
struct stat sbuf;
|
||||||
int fd;
|
int fd, count = 0;
|
||||||
|
uint32_t state = 0;
|
||||||
|
|
||||||
if (prefix == NULL) {
|
if (prefix == NULL) {
|
||||||
prefix = name;
|
prefix = name;
|
||||||
name = NULL;
|
name = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_read_path(path, sizeof(path), prefix, name) == 0) {
|
while (true) {
|
||||||
pw_log_debug(NAME" %p: can't load config '%s': %m", conf, path);
|
if (get_read_path(path, sizeof(path), prefix, name, useronly, &state) <= 0)
|
||||||
return -ENOENT;
|
break;
|
||||||
}
|
|
||||||
if ((fd = open(path, O_CLOEXEC | O_RDONLY)) < 0) {
|
|
||||||
pw_log_warn(NAME" %p: error loading config '%s': %m", conf, path);
|
|
||||||
return -errno;
|
|
||||||
}
|
|
||||||
|
|
||||||
pw_log_info(NAME" %p: loading config '%s'", conf, path);
|
pw_log_info(NAME" %p: loading config '%s'", conf, path);
|
||||||
if (fstat(fd, &sbuf) < 0)
|
if ((fd = open(path, O_CLOEXEC | O_RDONLY)) < 0) {
|
||||||
goto error_close;
|
pw_log_warn(NAME" %p: error opening '%s': %m", conf, path);
|
||||||
if ((data = mmap(NULL, sbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED)
|
continue;
|
||||||
goto error_close;
|
}
|
||||||
|
|
||||||
|
data = NULL;
|
||||||
|
if (fstat(fd, &sbuf) < 0) {
|
||||||
|
pw_log_warn(NAME" %p: error stat '%s': %m", conf, path);
|
||||||
|
} else if ((data = mmap(NULL, sbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED) {
|
||||||
|
pw_log_warn(NAME" %p: error mmap '%s': %m", conf, path);
|
||||||
|
data = NULL;
|
||||||
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
pw_properties_update_string(conf, data, sbuf.st_size);
|
if (data != NULL) {
|
||||||
|
count += pw_properties_update_string(conf, data, sbuf.st_size);
|
||||||
munmap(data, sbuf.st_size);
|
munmap(data, sbuf.st_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (count == 0)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error_close:
|
|
||||||
close(fd);
|
|
||||||
return -errno;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SPA_EXPORT
|
SPA_EXPORT
|
||||||
int pw_conf_load_conf(const char *prefix, const char *name, struct pw_properties *conf)
|
int pw_conf_load_conf(const char *prefix, const char *name, struct pw_properties *conf)
|
||||||
{
|
{
|
||||||
return conf_load(prefix, name, conf);
|
return conf_load(prefix, name, false, conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
SPA_EXPORT
|
SPA_EXPORT
|
||||||
int pw_conf_load_state(const char *prefix, const char *name, struct pw_properties *conf)
|
int pw_conf_load_state(const char *prefix, const char *name, struct pw_properties *conf)
|
||||||
{
|
{
|
||||||
return conf_load(prefix, name, conf);
|
return conf_load(prefix, name, true, conf);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* context.spa-libs = {
|
/* context.spa-libs = {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue