config-parser: Honor XDG_CONFIG_DIRS
This set of changes adds support for searching for a given config file
in the directories listed in $XDG_CONFIG_DIRS if it wasn't found in
$XDG_CONFIG_HOME or ~/.config. This allows packages to install custom
config files in /etc/xdg/weston, for example, thus allowing them to
avoid dealing with home directories.
To avoid a TOCTOU race the config file is actually open()ed during the
search. Its file descriptor is returned and stored in the compositor
for later use when performing subsequent config file parses.
Signed-off-by: Ossama Othman <ossama.othman@intel.com>
diff --git a/src/compositor.c b/src/compositor.c
index c16bf0c..89b9cef 100644
--- a/src/compositor.c
+++ b/src/compositor.c
@@ -2686,7 +2686,7 @@
weston_compositor_init(struct weston_compositor *ec,
struct wl_display *display,
int *argc, char *argv[],
- const char *config_file)
+ int config_fd)
{
struct wl_event_loop *loop;
struct xkb_rule_names xkb_names;
@@ -2703,7 +2703,9 @@
};
memset(&xkb_names, 0, sizeof(xkb_names));
- parse_config_file(config_file, cs, ARRAY_LENGTH(cs), ec);
+
+ ec->config_fd = config_fd;
+ parse_config_file(config_fd, cs, ARRAY_LENGTH(cs), ec);
ec->wl_display = display;
wl_signal_init(&ec->destroy_signal);
@@ -2789,6 +2791,8 @@
weston_plane_release(&ec->primary_plane);
wl_event_loop_destroy(ec->input_loop);
+
+ close(ec->config_fd);
}
WL_EXPORT void
@@ -2945,12 +2949,12 @@
static int
load_modules(struct weston_compositor *ec, const char *modules,
- int *argc, char *argv[], const char *config_file)
+ int *argc, char *argv[])
{
const char *p, *end;
char buffer[256];
int (*module_init)(struct weston_compositor *ec,
- int *argc, char *argv[], const char *config_file);
+ int *argc, char *argv[]);
if (modules == NULL)
return 0;
@@ -2961,7 +2965,7 @@
snprintf(buffer, sizeof buffer, "%.*s", (int) (end - p), p);
module_init = load_module(buffer, "module_init");
if (module_init)
- module_init(ec, argc, argv, config_file);
+ module_init(ec, argc, argv);
p = end;
while (*p == ',')
p++;
@@ -3087,8 +3091,8 @@
struct wl_event_loop *loop;
struct weston_compositor
*(*backend_init)(struct wl_display *display,
- int *argc, char *argv[], const char *config_file);
- int i;
+ int *argc, char *argv[], int config_fd);
+ int i, config_fd;
char *backend = NULL;
const char *modules = "desktop-shell.so", *option_modules = NULL;
char *log = NULL;
@@ -3096,7 +3100,6 @@
int32_t help = 0;
char *socket_name = "wayland-0";
int32_t version = 0;
- char *config_file;
const struct config_key core_config_keys[] = {
{ "modules", CONFIG_KEY_STRING, &modules },
@@ -3162,14 +3165,14 @@
backend = WESTON_NATIVE_BACKEND;
}
- config_file = config_file_path("weston.ini");
- parse_config_file(config_file, cs, ARRAY_LENGTH(cs), NULL);
+ config_fd = open_config_file("weston.ini");
+ parse_config_file(config_fd, cs, ARRAY_LENGTH(cs), NULL);
backend_init = load_module(backend, "backend_init");
if (!backend_init)
exit(EXIT_FAILURE);
- ec = backend_init(display, &argc, argv, config_file);
+ ec = backend_init(display, &argc, argv, config_fd);
if (ec == NULL) {
weston_log("fatal: failed to create compositor\n");
exit(EXIT_FAILURE);
@@ -3182,13 +3185,11 @@
setenv("WAYLAND_DISPLAY", socket_name, 1);
- if (load_modules(ec, modules, &argc, argv, config_file) < 0)
+ if (load_modules(ec, modules, &argc, argv) < 0)
goto out;
- if (load_modules(ec, option_modules, &argc, argv, config_file) < 0)
+ if (load_modules(ec, option_modules, &argc, argv) < 0)
goto out;
- free(config_file);
-
for (i = 1; i < argc; i++)
weston_log("fatal: unhandled option: %s\n", argv[i]);
if (argc > 1) {