From fd70ea6b31b4ab7629a8d6ca3fab2c1121d5d031 Mon Sep 17 00:00:00 2001 From: Orestis Floros Date: Tue, 10 Jul 2018 05:04:34 +0300 Subject: [PATCH] Correct XDG paths precedence for config files Fixes #3323 --- include/libi3.h | 10 ++++---- libi3/get_config_path.c | 53 +++++++++++++++++++++++------------------ man/i3.man | 8 +++---- src/config.c | 3 ++- 4 files changed, 41 insertions(+), 33 deletions(-) diff --git a/include/libi3.h b/include/libi3.h index b7a1e2aa2..ebddee96a 100644 --- a/include/libi3.h +++ b/include/libi3.h @@ -506,11 +506,11 @@ int logical_px(const int logical); char *resolve_tilde(const char *path); /** - * Get the path of the first configuration file found. If override_configpath - * is specified, that path is returned and saved for further calls. Otherwise, - * checks the home directory first, then the system directory first, always - * taking into account the XDG Base Directory Specification ($XDG_CONFIG_HOME, - * $XDG_CONFIG_DIRS) + * Get the path of the first configuration file found. If override_configpath is + * specified, that path is returned and saved for further calls. Otherwise, + * checks the home directory first, then the system directory, always taking + * into account the XDG Base Directory Specification ($XDG_CONFIG_HOME, + * $XDG_CONFIG_DIRS). * */ char *get_config_path(const char *override_configpath, bool use_system_paths); diff --git a/libi3/get_config_path.c b/libi3/get_config_path.c index efece5cde..4909e116b 100644 --- a/libi3/get_config_path.c +++ b/libi3/get_config_path.c @@ -21,11 +21,11 @@ static bool path_exists(const char *path) { } /* - * Get the path of the first configuration file found. If override_configpath - * is specified, that path is returned and saved for further calls. Otherwise, - * checks the home directory first, then the system directory first, always - * taking into account the XDG Base Directory Specification ($XDG_CONFIG_HOME, - * $XDG_CONFIG_DIRS) + * Get the path of the first configuration file found. If override_configpath is + * specified, that path is returned and saved for further calls. Otherwise, + * checks the home directory first, then the system directory, always taking + * into account the XDG Base Directory Specification ($XDG_CONFIG_HOME, + * $XDG_CONFIG_DIRS). * */ char *get_config_path(const char *override_configpath, bool use_system_paths) { @@ -38,40 +38,41 @@ char *get_config_path(const char *override_configpath, bool use_system_paths) { return sstrdup(saved_configpath); } - if (saved_configpath != NULL) + if (saved_configpath != NULL) { return sstrdup(saved_configpath); + } - /* 1: check the traditional path under the home directory */ - config_path = resolve_tilde("~/.i3/config"); - if (path_exists(config_path)) - return config_path; - free(config_path); - - /* 2: check for $XDG_CONFIG_HOME/i3/config */ - if ((xdg_config_home = getenv("XDG_CONFIG_HOME")) == NULL) + /* 1: check for $XDG_CONFIG_HOME/i3/config */ + if ((xdg_config_home = getenv("XDG_CONFIG_HOME")) == NULL) { xdg_config_home = "~/.config"; + } xdg_config_home = resolve_tilde(xdg_config_home); sasprintf(&config_path, "%s/i3/config", xdg_config_home); free(xdg_config_home); - if (path_exists(config_path)) + if (path_exists(config_path)) { return config_path; + } + free(config_path); + + /* 2: check the traditional path under the home directory */ + config_path = resolve_tilde("~/.i3/config"); + if (path_exists(config_path)) { + return config_path; + } free(config_path); /* The below paths are considered system-level, and can be skipped if the * caller only wants user-level configs. */ - if (!use_system_paths) + if (!use_system_paths) { return NULL; + } - /* 3: check the traditional path under /etc */ - config_path = SYSCONFDIR "/i3/config"; - if (path_exists(config_path)) - return sstrdup(config_path); - - /* 4: check for $XDG_CONFIG_DIRS/i3/config */ - if ((xdg_config_dirs = getenv("XDG_CONFIG_DIRS")) == NULL) + /* 3: check for $XDG_CONFIG_DIRS/i3/config */ + if ((xdg_config_dirs = getenv("XDG_CONFIG_DIRS")) == NULL) { xdg_config_dirs = SYSCONFDIR "/xdg"; + } char *buf = sstrdup(xdg_config_dirs); char *tok = strtok(buf, ":"); @@ -88,5 +89,11 @@ char *get_config_path(const char *override_configpath, bool use_system_paths) { } free(buf); + /* 4: check the traditional path under /etc */ + config_path = SYSCONFDIR "/i3/config"; + if (path_exists(config_path)) { + return sstrdup(config_path); + } + return NULL; } diff --git a/man/i3.man b/man/i3.man index 1f595ce82..640b5ac81 100644 --- a/man/i3.man +++ b/man/i3.man @@ -170,10 +170,10 @@ Exits i3. When starting, i3 looks for configuration files in the following order: -1. ~/.i3/config -2. ~/.config/i3/config (or $XDG_CONFIG_HOME/i3/config if set) -3. /etc/i3/config -4. /etc/xdg/i3/config (or $XDG_CONFIG_DIRS/i3/config if set) +1. ~/.config/i3/config (or $XDG_CONFIG_HOME/i3/config if set) +2. ~/.i3/config +3. /etc/xdg/i3/config (or $XDG_CONFIG_DIRS/i3/config if set) +4. /etc/i3/config You can specify a custom path using the -c option. diff --git a/src/config.c b/src/config.c index de149ce7d..ab19bae31 100644 --- a/src/config.c +++ b/src/config.c @@ -49,7 +49,8 @@ bool parse_configuration(const char *override_configpath, bool use_nagbar) { char *path = get_config_path(override_configpath, true); if (path == NULL) { die("Unable to find the configuration file (looked at " - "~/.i3/config, $XDG_CONFIG_HOME/i3/config, " SYSCONFDIR "/i3/config and $XDG_CONFIG_DIRS/i3/config)"); + "$XDG_CONFIG_HOME/i3/config, ~/.i3/config, $XDG_CONFIG_DIRS/i3/config " + "and " SYSCONFDIR "/i3/config)"); } LOG("Parsing configfile %s\n", path);