[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,
>                                 &param);
>  }
> 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, &param);
> + return rpi_compositor_create(display, argc, argv, config_fd, &param);
>  }
> 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