[PATCH] config-parser: Honor the XDG_CONFIG_DIRS environment variable
Kristian Høgsberg
hoegsberg at gmail.com
Mon May 13 17:46:28 PDT 2013
On Mon, May 13, 2013 at 04:31:06PM -0700, Othman, Ossama wrote:
> Hi Kristian,
>
> Here's another revision of the patch that attempts to implement your
> suggested simplification, as well as address the TOCTOU race in previous
> revisions of the patch. The module entry point signature changed slightly
> because of the latter. Note that I had to modify the strchrnul() loop
> slightly from what you suggested since the "next" string ended up beginning
> with a colon ':' after the first iteration. I'm not exactly happy with my
> solution (p =( *next == ':' ? next + 1 : next)). Please let me know what
> you think.
I think it's good to go - however, inlining the patch messed up the
whitespace. Ideally, send patches using git send-email, which can be
configured to use smtp servers, and you can pass --annotate if you
want to add a message or comment to the patch (put it after the ---
that indicates the end of the commit message). Or as a last resort,
attach the patch.
As for the next thing, good catch. I'd do something like
for (p = config_dirs; p != NULL; p = next) {
next = strchrnul(p, ':');
if (*next == ':')
next++;
...
to keep the for (...) more readable.
Kristian
> Thanks!
> -Ossama
>
> ---
>
> From 528848247242cdf476e05569b5abef029d438f79 Mon Sep 17 00:00:00 2001
> From: Ossama Othman <ossama.othman at intel.com>
> Date: Mon, 13 May 2013 16:12:32 -0700
> Subject: [PATCH] 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 at intel.com>
> ---
> clients/desktop-shell.c | 8 ++--
> clients/tablet-shell.c | 8 ++--
> clients/terminal.c | 8 ++--
> clients/window.c | 8 ++--
> man/weston.ini.man | 12 +++++-
> shared/config-parser.c | 92
> ++++++++++++++++++++++++++++++---------------
> shared/config-parser.h | 6 +--
> src/cms-static.c | 4 +-
> src/compositor-drm.c | 10 ++---
> src/compositor-fbdev.c | 8 ++--
> src/compositor-headless.c | 8 ++--
> src/compositor-rdp.c | 4 +-
> src/compositor-rpi.c | 8 ++--
> src/compositor-wayland.c | 8 ++--
> src/compositor-x11.c | 10 ++---
> src/compositor.c | 31 +++++++--------
> src/compositor.h | 8 ++--
> src/shell.c | 8 ++--
> src/tablet-shell.c | 2 +-
> src/text-backend.c | 9 +++--
> src/xwayland/launcher.c | 2 +-
> tests/weston-test.c | 2 +-
> 22 files changed, 154 insertions(+), 110 deletions(-)
>
> diff --git a/clients/desktop-shell.c b/clients/desktop-shell.c
> index 38af6c6..3949975 100644
> --- a/clients/desktop-shell.c
> +++ b/clients/desktop-shell.c
> @@ -1090,7 +1090,7 @@ add_default_launcher(struct desktop *desktop)
> int main(int argc, char *argv[])
> {
> struct desktop desktop = { 0 };
> - char *config_file;
> + int config_fd;
> struct output *output;
> int ret;
>
> @@ -1122,11 +1122,11 @@ int main(int argc, char *argv[])
>
> grab_surface_create(&desktop);
>
> - config_file = config_file_path("weston.ini");
> - ret = parse_config_file(config_file,
> + config_fd = open_config_file("weston.ini");
> + ret = parse_config_file(config_fd,
> config_sections, ARRAY_LENGTH(config_sections),
> &desktop);
> - free(config_file);
> + close(config_fd);
> if (ret < 0)
> add_default_launcher(&desktop);
>
> diff --git a/clients/tablet-shell.c b/clients/tablet-shell.c
> index 99d66f2..3d5e79a 100644
> --- a/clients/tablet-shell.c
> +++ b/clients/tablet-shell.c
> @@ -456,7 +456,7 @@ int main(int argc, char *argv[])
> {
> struct tablet tablet = { 0 };
> struct display *display;
> - char *config_file;
> + int config_fd;
> struct output *output;
>
> display = display_create(&argc, argv);
> @@ -478,11 +478,11 @@ int main(int argc, char *argv[])
>
> wl_list_init(&tablet.homescreen->launcher_list);
>
> - config_file = config_file_path("weston.ini");
> - parse_config_file(config_file,
> + config_fd = open_config_file("weston.ini");
> + parse_config_file(config_fd,
> config_sections, ARRAY_LENGTH(config_sections),
> &tablet);
> - free(config_file);
> + close(config_fd);
>
> signal(SIGCHLD, sigchild_handler);
>
> diff --git a/clients/terminal.c b/clients/terminal.c
> index e80e0e5..f11a6cc 100644
> --- a/clients/terminal.c
> +++ b/clients/terminal.c
> @@ -2671,17 +2671,17 @@ int main(int argc, char *argv[])
> {
> struct display *d;
> struct terminal *terminal;
> - char *config_file;
> + int config_fd;
>
> option_shell = getenv("SHELL");
> if (!option_shell)
> option_shell = "/bin/bash";
>
> - config_file = config_file_path("weston.ini");
> - parse_config_file(config_file,
> + config_fd = open_config_file("weston.ini");
> + parse_config_file(config_fd,
> config_sections, ARRAY_LENGTH(config_sections),
> NULL);
> - free(config_file);
> + close(config_fd);
>
> parse_options(terminal_options,
> ARRAY_LENGTH(terminal_options), &argc, argv);
> diff --git a/clients/window.c b/clients/window.c
> index 1562957..a742b2f 100644
> --- a/clients/window.c
> +++ b/clients/window.c
> @@ -1188,7 +1188,7 @@ static const struct cursor_alternatives cursors[] = {
> static void
> create_cursors(struct display *display)
> {
> - char *config_file;
> + int config_fd;
> char *theme = NULL;
> unsigned int size = 32;
> unsigned int i, j;
> @@ -1201,9 +1201,9 @@ create_cursors(struct display *display)
> { "shell", shell_keys, ARRAY_LENGTH(shell_keys), NULL },
> };
>
> - config_file = config_file_path("weston.ini");
> - parse_config_file(config_file, cs, ARRAY_LENGTH(cs), NULL);
> - free(config_file);
> + config_fd = open_config_file("weston.ini");
> + parse_config_file(config_fd, cs, ARRAY_LENGTH(cs), NULL);
> + close(config_fd);
>
> display->cursor_theme = wl_cursor_theme_load(theme, size, display->shm);
> display->cursors =
> diff --git a/man/weston.ini.man b/man/weston.ini.man
> index 2287730..d37654a 100644
> --- a/man/weston.ini.man
> +++ b/man/weston.ini.man
> @@ -24,7 +24,10 @@ server is started:
> .nf
> .BR "$XDG_CONFIG_HOME/weston.ini " "(if $XDG_CONFIG_HOME is set)"
> .BR "$HOME/.config/weston.ini " "(if $HOME is set)"
> -.BR "<current dir>/weston.ini " "(if both variables were not set)"
> +.B "weston/weston.ini in each"
> +.BR "\ \ \ \ $XDG_CONFIG_DIR " "(if $XDG_CONFIG_DIRS is set)"
> +.BR "/etc/xdg/weston/weston.ini " "(if $XDG_CONFIG_DIRS is not set)"
> +.BR "<current dir>/weston.ini " "(if no variables were set)"
> .fi
> .RE
> .PP
> @@ -32,7 +35,12 @@ where environment variable
> .B $HOME
> is the user's home directory, and
> .B $XDG_CONFIG_HOME
> -is the user specific configuration directory.
> +is the user specific configuration directory, and
> +.B $XDG_CONFIG_DIRS
> +is a colon
> +.B ':'
> +delimited listed of configuration base directories, such as
> +.BR /etc/xdg-foo:/etc/xdg .
> .PP
> The
> .I weston.ini
> diff --git a/shared/config-parser.c b/shared/config-parser.c
> index 10ff86a..e988a89 100644
> --- a/shared/config-parser.c
> +++ b/shared/config-parser.c
> @@ -20,11 +20,17 @@
> * OF THIS SOFTWARE.
> */
>
> +#define _GNU_SOURCE /* for stchrnul() */
> #include <string.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <assert.h>
> #include <ctype.h>
> +#include <limits.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <fcntl.h>
> +#include <unistd.h>
>
> #include "config-parser.h"
>
> @@ -86,7 +92,7 @@ handle_key(const struct config_key *key, const char
> *value)
> }
>
> int
> -parse_config_file(const char *path,
> +parse_config_file(int fd,
> const struct config_section *sections, int num_sections,
> void *data)
> {
> @@ -95,12 +101,17 @@ parse_config_file(const char *path,
> const struct config_section *current = NULL;
> int i;
>
> - fp = fopen(path, "r");
> + if (fd == -1)
> + return -1;
> +
> + fp = fdopen(dup(fd), "r");
> if (fp == NULL) {
> - fprintf(stderr, "couldn't open %s\n", path);
> + perror("couldn't open config file");
> return -1;
> }
>
> + rewind(fp);
> +
> while (fgets(line, sizeof line, fp)) {
> if (line[0] == '#' || line[0] == '\n') {
> continue;
> @@ -151,37 +162,58 @@ parse_config_file(const char *path,
> return 0;
> }
>
> -char *
> -config_file_path(const char *name)
> +int
> +open_config_file(const char *name)
> {
> - const char dotconf[] = "/.config/";
> - const char *config_dir;
> - const char *home_dir;
> - char *path;
> - size_t size;
> -
> - config_dir = getenv("XDG_CONFIG_HOME");
> - if (!config_dir) {
> - home_dir = getenv("HOME");
> - if (!home_dir) {
> - fprintf(stderr, "HOME is not set, using cwd.\n");
> - return strdup(name);
> - }
> + const char *config_dir = getenv("XDG_CONFIG_HOME");
> + const char *home_dir = getenv("HOME");
> + const char *config_dirs = getenv("XDG_CONFIG_DIRS");
> + char path[PATH_MAX];
> + const char *p, *next;
> + int fd;
> +
> + /* Precedence is given to config files in the home directory,
> + * and then to directories listed in XDG_CONFIG_DIRS and
> + * finally to the current working directory. */
> +
> + /* $XDG_CONFIG_HOME */
> + if (config_dir) {
> + snprintf(path, sizeof path, "%s/%s", config_dir, name);
> + fd = open(path, O_RDONLY | O_CLOEXEC);
> + if (fd >= 0)
> + return fd;
> + }
> +
> + /* $HOME/.config */
> + if (home_dir) {
> + snprintf(path, sizeof path, "%s/.config/%s", home_dir, name);
> + fd = open(path, O_RDONLY | O_CLOEXEC);
> + if (fd >= 0)
> + return fd;
> + }
>
> - size = strlen(home_dir) + sizeof dotconf + strlen(name);
> - path = malloc(size);
> - if (!path)
> - return NULL;
> + /* For each $XDG_CONFIG_DIRS: weston/<config_file> */
> + if (!config_dirs)
> + config_dirs = "/etc/xdg"; /* See XDG base dir spec. */
>
> - snprintf(path, size, "%s%s%s", home_dir, dotconf, name);
> - return path;
> + for (p = config_dirs; *p; p = (*next == ':' ? next + 1 : next)) {
> + next = strchrnul(p, ':');
> + snprintf(path, sizeof path, "%.*s/weston/%s", next - p, p, name);
> + fd = open(path, O_RDONLY | O_CLOEXEC);
> + if (fd >= 0)
> + return fd;
> }
>
> - size = strlen(config_dir) + 1 + strlen(name) + 1;
> - path = malloc(size);
> - if (!path)
> - return NULL;
> + /* Current working directory. */
> + snprintf(path, sizeof path, "./%s", name);
> + fd = open(path, O_RDONLY | O_CLOEXEC);
> +
> + if (fd >= 0)
> + fprintf(stderr,
> + "using config in current working directory: %s\n",
> + path);
> + else
> + fprintf(stderr, "config file \"%s\" not found.\n", name);
>
> - snprintf(path, size, "%s/%s", config_dir, name);
> - return path;
> + return fd;
> }
> diff --git a/shared/config-parser.h b/shared/config-parser.h
> index 1d0ee3f..b4347d7 100644
> --- a/shared/config-parser.h
> +++ b/shared/config-parser.h
> @@ -48,12 +48,12 @@ struct config_section {
> };
>
> int
> -parse_config_file(const char *path,
> +parse_config_file(int config_fd,
> const struct config_section *sections, int num_sections,
> void *data);
>
> -char *
> -config_file_path(const char *name);
> +int
> +open_config_file(const char *name);
>
> enum weston_option_type {
> WESTON_OPTION_INTEGER,
> diff --git a/src/cms-static.c b/src/cms-static.c
> index be8e63e..94fea99 100644
> --- a/src/cms-static.c
> +++ b/src/cms-static.c
> @@ -131,7 +131,7 @@ output_section_done(void *data)
>
> WL_EXPORT int
> module_init(struct weston_compositor *ec,
> - int *argc, char *argv[], const char *config_file)
> + int *argc, char *argv[])
> {
> struct cms_static *cms;
> struct weston_output *output;
> @@ -157,7 +157,7 @@ module_init(struct weston_compositor *ec,
> ARRAY_LENGTH(drm_config_keys), output_section_done },
> };
>
> - parse_config_file(config_file, config_section,
> + parse_config_file(ec->config_fd, config_section,
> ARRAY_LENGTH(config_section), cms);
>
> cms->destroy_listener.notify = cms_notifier_destroy;
> diff --git a/src/compositor-drm.c b/src/compositor-drm.c
> index bb8ea46..b188a1a 100644
> --- a/src/compositor-drm.c
> +++ b/src/compositor-drm.c
> @@ -2340,7 +2340,7 @@ planes_binding(struct weston_seat *seat, uint32_t
> time, uint32_t key, void *data
> static struct weston_compositor *
> drm_compositor_create(struct wl_display *display,
> int connector, const char *seat, int tty, int pixman,
> - int *argc, char *argv[], const char *config_file)
> + int *argc, char *argv[], int config_fd)
> {
> struct drm_compositor *ec;
> struct udev_device *drm_device;
> @@ -2363,7 +2363,7 @@ drm_compositor_create(struct wl_display *display,
> ec->use_pixman = pixman;
>
> if (weston_compositor_init(&ec->base, display, argc, argv,
> - config_file) < 0) {
> + config_fd) < 0) {
> weston_log("%s failed\n", __func__);
> goto err_base;
> }
> @@ -2644,7 +2644,7 @@ output_section_done(void *data)
>
> WL_EXPORT struct weston_compositor *
> backend_init(struct wl_display *display, int *argc, char *argv[],
> - const char *config_file)
> + int config_fd)
> {
> int connector = 0, tty = 0, use_pixman = 0;
> const char *seat = default_seat;
> @@ -2672,9 +2672,9 @@ backend_init(struct wl_display *display, int *argc,
> char *argv[],
> ARRAY_LENGTH(drm_config_keys), output_section_done },
> };
>
> - parse_config_file(config_file, config_section,
> + parse_config_file(config_fd, config_section,
> ARRAY_LENGTH(config_section), NULL);
>
> return drm_compositor_create(display, connector, seat, tty, use_pixman,
> - argc, argv, config_file);
> + argc, argv, config_fd);
> }
> diff --git a/src/compositor-fbdev.c b/src/compositor-fbdev.c
> index 0f45858..21028a5 100644
> --- a/src/compositor-fbdev.c
> +++ b/src/compositor-fbdev.c
> @@ -835,7 +835,7 @@ switch_vt_binding(struct weston_seat *seat, uint32_t
> time, uint32_t key, void *d
>
> static struct weston_compositor *
> fbdev_compositor_create(struct wl_display *display, int *argc, char
> *argv[],
> - const char *config_file, struct fbdev_parameters
> *param)
> + int config_fd, struct fbdev_parameters *param)
> {
> struct fbdev_compositor *compositor;
> const char *seat = default_seat;
> @@ -848,7 +848,7 @@ fbdev_compositor_create(struct wl_display *display, int
> *argc, char *argv[],
> return NULL;
>
> if (weston_compositor_init(&compositor->base, display, argc, argv,
> - config_file) < 0)
> + config_fd) < 0)
> goto out_free;
>
> compositor->udev = udev_new();
> @@ -906,7 +906,7 @@ out_free:
>
> WL_EXPORT struct weston_compositor *
> backend_init(struct wl_display *display, int *argc, char *argv[],
> - const char *config_file)
> + int config_fd)
> {
> /* TODO: Ideally, available frame buffers should be enumerated using
> * udev, rather than passing a device node in as a parameter. */
> @@ -922,6 +922,6 @@ backend_init(struct wl_display *display, int *argc,
> char *argv[],
>
> parse_options(fbdev_options, ARRAY_LENGTH(fbdev_options), argc, argv);
>
> - return fbdev_compositor_create(display, argc, argv, config_file,
> + return fbdev_compositor_create(display, argc, argv, config_fd,
> ¶m);
> }
> diff --git a/src/compositor-headless.c b/src/compositor-headless.c
> index 4720329..0df0f7d 100644
> --- a/src/compositor-headless.c
> +++ b/src/compositor-headless.c
> @@ -158,7 +158,7 @@ headless_destroy(struct weston_compositor *ec)
> static struct weston_compositor *
> headless_compositor_create(struct wl_display *display,
> int width, int height, const char *display_name,
> - int *argc, char *argv[], const char *config_file)
> + int *argc, char *argv[], int config_fd)
> {
> struct headless_compositor *c;
>
> @@ -169,7 +169,7 @@ headless_compositor_create(struct wl_display *display,
> memset(c, 0, sizeof *c);
>
> if (weston_compositor_init(&c->base, display, argc, argv,
> - config_file) < 0)
> + config_fd) < 0)
> goto err_free;
>
> weston_seat_init(&c->fake_seat, &c->base);
> @@ -194,7 +194,7 @@ err_free:
>
> WL_EXPORT struct weston_compositor *
> backend_init(struct wl_display *display, int *argc, char *argv[],
> - const char *config_file)
> + int config_fd)
> {
> int width = 1024, height = 640;
> char *display_name = NULL;
> @@ -208,5 +208,5 @@ backend_init(struct wl_display *display, int *argc,
> char *argv[],
> ARRAY_LENGTH(headless_options), argc, argv);
>
> return headless_compositor_create(display, width, height, display_name,
> - argc, argv, config_file);
> + argc, argv, config_fd);
> }
> diff --git a/src/compositor-rdp.c b/src/compositor-rdp.c
> index 51ef475..0dae963 100644
> --- a/src/compositor-rdp.c
> +++ b/src/compositor-rdp.c
> @@ -928,7 +928,7 @@ rdp_incoming_peer(freerdp_listener *instance,
> freerdp_peer *client)
> static struct weston_compositor *
> rdp_compositor_create(struct wl_display *display,
> struct rdp_compositor_config *config,
> - int *argc, char *argv[], const char *config_file)
> + int *argc, char *argv[], int config_fd)
> {
> struct rdp_compositor *c;
> char *fd_str;
> @@ -941,7 +941,7 @@ rdp_compositor_create(struct wl_display *display,
> memset(c, 0, sizeof *c);
>
> if (weston_compositor_init(&c->base, display, argc, argv,
> - config_file) < 0)
> + config_fd) < 0)
> goto err_free;
>
> weston_seat_init(&c->main_seat, &c->base);
> diff --git a/src/compositor-rpi.c b/src/compositor-rpi.c
> index 8f3f2e9..3cb2b56 100644
> --- a/src/compositor-rpi.c
> +++ b/src/compositor-rpi.c
> @@ -1441,7 +1441,7 @@ struct rpi_parameters {
>
> static struct weston_compositor *
> rpi_compositor_create(struct wl_display *display, int *argc, char *argv[],
> - const char *config_file, struct rpi_parameters *param)
> + int config_fd, struct rpi_parameters *param)
> {
> struct rpi_compositor *compositor;
> const char *seat = default_seat;
> @@ -1464,7 +1464,7 @@ rpi_compositor_create(struct wl_display *display, int
> *argc, char *argv[],
> return NULL;
>
> if (weston_compositor_init(&compositor->base, display, argc, argv,
> - config_file) < 0)
> + config_fd) < 0)
> goto out_free;
>
> compositor->udev = udev_new();
> @@ -1554,7 +1554,7 @@ out_free:
>
> WL_EXPORT struct weston_compositor *
> backend_init(struct wl_display *display, int *argc, char *argv[],
> - const char *config_file)
> + int config_fd)
> {
> struct rpi_parameters param = {
> .tty = 0, /* default to current tty */
> @@ -1571,5 +1571,5 @@ backend_init(struct wl_display *display, int *argc,
> char *argv[],
>
> parse_options(rpi_options, ARRAY_LENGTH(rpi_options), argc, argv);
>
> - return rpi_compositor_create(display, argc, argv, config_file, ¶m);
> + return rpi_compositor_create(display, argc, argv, config_fd, ¶m);
> }
> diff --git a/src/compositor-wayland.c b/src/compositor-wayland.c
> index 44d234c..4112401 100644
> --- a/src/compositor-wayland.c
> +++ b/src/compositor-wayland.c
> @@ -721,7 +721,7 @@ wayland_destroy(struct weston_compositor *ec)
> static struct weston_compositor *
> wayland_compositor_create(struct wl_display *display,
> int width, int height, const char *display_name,
> - int *argc, char *argv[], const char *config_file)
> + int *argc, char *argv[], int config_fd)
> {
> struct wayland_compositor *c;
> struct wl_event_loop *loop;
> @@ -734,7 +734,7 @@ wayland_compositor_create(struct wl_display *display,
> memset(c, 0, sizeof *c);
>
> if (weston_compositor_init(&c->base, display, argc, argv,
> - config_file) < 0)
> + config_fd) < 0)
> goto err_free;
>
> c->parent.wl_display = wl_display_connect(display_name);
> @@ -797,7 +797,7 @@ err_free:
>
> WL_EXPORT struct weston_compositor *
> backend_init(struct wl_display *display, int *argc, char *argv[],
> - const char *config_file)
> + int config_fd)
> {
> int width = 1024, height = 640;
> char *display_name = NULL;
> @@ -812,5 +812,5 @@ backend_init(struct wl_display *display, int *argc,
> char *argv[],
> ARRAY_LENGTH(wayland_options), argc, argv);
>
> return wayland_compositor_create(display, width, height, display_name,
> - argc, argv, config_file);
> + argc, argv, config_fd);
> }
> diff --git a/src/compositor-x11.c b/src/compositor-x11.c
> index 21304a0..ea0d4b9 100644
> --- a/src/compositor-x11.c
> +++ b/src/compositor-x11.c
> @@ -1383,7 +1383,7 @@ x11_compositor_create(struct wl_display *display,
> int fullscreen,
> int no_input,
> int use_pixman,
> - int *argc, char *argv[], const char *config_file)
> + int *argc, char *argv[], int config_fd)
> {
> struct x11_compositor *c;
> struct x11_configured_output *o;
> @@ -1401,7 +1401,7 @@ x11_compositor_create(struct wl_display *display,
> memset(c, 0, sizeof *c);
>
> if (weston_compositor_init(&c->base, display, argc, argv,
> - config_file) < 0)
> + config_fd) < 0)
> goto err_free;
>
> c->dpy = XOpenDisplay(NULL);
> @@ -1574,7 +1574,7 @@ err_free:
>
> WL_EXPORT struct weston_compositor *
> backend_init(struct wl_display *display, int *argc, char *argv[],
> - const char *config_file)
> + int config_fd)
> {
> int fullscreen = 0;
> int no_input = 0;
> @@ -1604,12 +1604,12 @@ backend_init(struct wl_display *display, int *argc,
> char *argv[],
> ARRAY_LENGTH(x11_config_keys), output_section_done },
> };
>
> - parse_config_file(config_file, config_section,
> + parse_config_file(config_fd, config_section,
> ARRAY_LENGTH(config_section), NULL);
>
> return x11_compositor_create(display,
> fullscreen,
> no_input,
> use_pixman,
> - argc, argv, config_file);
> + argc, argv, config_fd);
> }
> diff --git a/src/compositor.c b/src/compositor.c
> index c1f90ca..fa5cb00 100644
> --- a/src/compositor.c
> +++ b/src/compositor.c
> @@ -2685,7 +2685,7 @@ WL_EXPORT int
> 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;
> @@ -2702,7 +2702,9 @@ weston_compositor_init(struct weston_compositor *ec,
> };
>
> 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);
> @@ -2788,6 +2790,8 @@ weston_compositor_shutdown(struct weston_compositor
> *ec)
> weston_plane_release(&ec->primary_plane);
>
> wl_event_loop_destroy(ec->input_loop);
> +
> + close(ec->config_fd);
> }
>
> WL_EXPORT void
> @@ -2944,12 +2948,12 @@ load_module(const char *name, const char
> *entrypoint)
>
> 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;
> @@ -2960,7 +2964,7 @@ load_modules(struct weston_compositor *ec, const char
> *modules,
> 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++;
> @@ -3086,8 +3090,8 @@ int main(int argc, char *argv[])
> 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;
> @@ -3095,7 +3099,6 @@ int main(int argc, char *argv[])
> 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 },
> @@ -3161,14 +3164,14 @@ int main(int argc, char *argv[])
> 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);
> @@ -3181,13 +3184,11 @@ int main(int argc, char *argv[])
>
> 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) {
> diff --git a/src/compositor.h b/src/compositor.h
> index d7aa005..44d217e 100644
> --- a/src/compositor.h
> +++ b/src/compositor.h
> @@ -546,6 +546,8 @@ struct weston_compositor {
> struct xkb_rule_names xkb_names;
> struct xkb_context *xkb_context;
> struct weston_xkb_info xkb_info;
> +
> + int config_fd;
> };
>
> struct weston_buffer_reference {
> @@ -988,7 +990,7 @@ weston_compositor_get_time(void);
>
> int
> weston_compositor_init(struct weston_compositor *ec, struct wl_display
> *display,
> - int *argc, char *argv[], const char *config_file);
> + int *argc, char *argv[], int config_fd);
> void
> weston_compositor_shutdown(struct weston_compositor *ec);
> void
> @@ -1126,11 +1128,11 @@ noop_renderer_init(struct weston_compositor *ec);
>
> struct weston_compositor *
> backend_init(struct wl_display *display, int *argc, char *argv[],
> - const char *config_file);
> + int config_fd);
>
> int
> module_init(struct weston_compositor *compositor,
> - int *argc, char *argv[], const char *config_file);
> + int *argc, char *argv[]);
>
> void
> weston_transformed_coord(int width, int height,
> diff --git a/src/shell.c b/src/shell.c
> index 5da649d..d5b5fcf 100644
> --- a/src/shell.c
> +++ b/src/shell.c
> @@ -375,7 +375,7 @@ get_animation_type(char *animation)
> }
>
> static void
> -shell_configuration(struct desktop_shell *shell, const char *config_file)
> +shell_configuration(struct desktop_shell *shell, int config_fd)
> {
> char *path = NULL;
> int duration = 60;
> @@ -400,7 +400,7 @@ shell_configuration(struct desktop_shell *shell, const
> char *config_file)
> { "screensaver", saver_keys, ARRAY_LENGTH(saver_keys), NULL },
> };
>
> - parse_config_file(config_file, cs, ARRAY_LENGTH(cs), shell);
> + parse_config_file(config_fd, cs, ARRAY_LENGTH(cs), shell);
>
> shell->screensaver.path = path;
> shell->screensaver.duration = duration * 1000;
> @@ -4286,7 +4286,7 @@ shell_add_bindings(struct weston_compositor *ec,
> struct desktop_shell *shell)
>
> WL_EXPORT int
> module_init(struct weston_compositor *ec,
> - int *argc, char *argv[], const char *config_file)
> + int *argc, char *argv[])
> {
> struct weston_seat *seat;
> struct desktop_shell *shell;
> @@ -4333,7 +4333,7 @@ module_init(struct weston_compositor *ec,
> wl_array_init(&shell->workspaces.array);
> wl_list_init(&shell->workspaces.client_list);
>
> - shell_configuration(shell, config_file);
> + shell_configuration(shell, ec->config_fd);
>
> for (i = 0; i < shell->workspaces.num; i++) {
> pws = wl_array_add(&shell->workspaces.array, sizeof *pws);
> diff --git a/src/tablet-shell.c b/src/tablet-shell.c
> index 7c75c1b..cae8acf 100644
> --- a/src/tablet-shell.c
> +++ b/src/tablet-shell.c
> @@ -527,7 +527,7 @@ tablet_shell_destroy(struct wl_listener *listener, void
> *data)
>
> WL_EXPORT int
> module_init(struct weston_compositor *compositor,
> - int *argc, char *argv[], const char *config_file)
> + int *argc, char *argv[])
> {
> struct tablet_shell *shell;
> struct wl_event_loop *loop;
> diff --git a/src/text-backend.c b/src/text-backend.c
> index 92efd9f..da62fd7 100644
> --- a/src/text-backend.c
> +++ b/src/text-backend.c
> @@ -23,6 +23,7 @@
>
> #include <stdlib.h>
> #include <string.h>
> +#include <unistd.h>
>
> #include "compositor.h"
> #include "text-server-protocol.h"
> @@ -885,7 +886,7 @@ handle_seat_created(struct wl_listener *listener,
> static void
> text_backend_configuration(struct text_backend *text_backend)
> {
> - char *config_file;
> + int config_fd;
> char *path = NULL;
>
> struct config_key input_method_keys[] = {
> @@ -896,9 +897,9 @@ text_backend_configuration(struct text_backend
> *text_backend)
> { "input-method", input_method_keys, ARRAY_LENGTH(input_method_keys),
> NULL }
> };
>
> - config_file = config_file_path("weston.ini");
> - parse_config_file(config_file, cs, ARRAY_LENGTH(cs), text_backend);
> - free(config_file);
> + config_fd = open_config_file("weston.ini");
> + parse_config_file(config_fd, cs, ARRAY_LENGTH(cs), text_backend);
> + close(config_fd);
>
> if (path)
> text_backend->input_method.path = path;
> diff --git a/src/xwayland/launcher.c b/src/xwayland/launcher.c
> index e50177e..664cf6c 100644
> --- a/src/xwayland/launcher.c
> +++ b/src/xwayland/launcher.c
> @@ -316,7 +316,7 @@ weston_xserver_destroy(struct wl_listener *l, void
> *data)
>
> WL_EXPORT int
> module_init(struct weston_compositor *compositor,
> - int *argc, char *argv[], const char *config_file)
> + int *argc, char *argv[])
>
> {
> struct wl_display *display = compositor->wl_display;
> diff --git a/tests/weston-test.c b/tests/weston-test.c
> index 612841b..b629c86 100644
> --- a/tests/weston-test.c
> +++ b/tests/weston-test.c
> @@ -225,7 +225,7 @@ idle_launch_client(void *data)
>
> WL_EXPORT int
> module_init(struct weston_compositor *ec,
> - int *argc, char *argv[], const char *config_file)
> + int *argc, char *argv[])
> {
> struct weston_test *test;
> struct wl_event_loop *loop;
> --
> 1.7.10.4
More information about the wayland-devel
mailing list