[PATCH] config-parser: Honor the XDG_CONFIG_DIRS environment variable

Othman, Ossama ossama.othman at intel.com
Mon May 13 16:31:06 PDT 2013


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.

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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20130513/3a583369/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-config-parser-Honor-XDG_CONFIG_DIRS.patch
Type: application/octet-stream
Size: 28422 bytes
Desc: not available
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20130513/3a583369/attachment-0001.obj>


More information about the wayland-devel mailing list