From b342d387a82ac2b99c54225eeaaad5a311b5f126 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sat, 19 Mar 2011 22:26:15 +0100 Subject: [PATCH] Handle saved_configpath in get_config_path, fix memleak in current_configpath handling, update atoms after reloading (Thanks fernandotcl) --- include/config.h | 2 +- include/x.h | 6 +++ src/cmdparse.y | 1 + src/config.c | 118 +++++++++++++++++++++++------------------------ src/main.c | 6 +-- src/x.c | 12 +++++ 6 files changed, 79 insertions(+), 66 deletions(-) diff --git a/include/config.h b/include/config.h index 79343ab0..55d597eb 100644 --- a/include/config.h +++ b/include/config.h @@ -22,7 +22,7 @@ #include "i3.h" typedef struct Config Config; -extern const char *current_configpath; +extern char *current_configpath; extern Config config; extern SLIST_HEAD(modes_head, Mode) modes; diff --git a/include/x.h b/include/x.h index da4147cc..6b0bae0e 100644 --- a/include/x.h +++ b/include/x.h @@ -79,4 +79,10 @@ void x_raise_con(Con *con); */ void x_set_name(Con *con, const char *name); +/** + * Sets up i3 specific atoms (I3_SOCKET_PATH and I3_CONFIG_PATH) + * + */ +void x_set_i3_atoms(); + #endif diff --git a/src/cmdparse.y b/src/cmdparse.y index 37605bb8..e15410a4 100644 --- a/src/cmdparse.y +++ b/src/cmdparse.y @@ -346,6 +346,7 @@ reload: { printf("reloading\n"); load_configuration(conn, NULL, true); + x_set_i3_atoms(); /* Send an IPC event just in case the ws names have changed */ ipc_send_event("workspace", I3_IPC_EVENT_WORKSPACE, "{\"change\":\"reload\"}"); } diff --git a/src/config.c b/src/config.c index 20b077b7..572b4ab9 100644 --- a/src/config.c +++ b/src/config.c @@ -19,7 +19,7 @@ #include "all.h" -const char *current_configpath = NULL; +char *current_configpath = NULL; Config config; struct modes_head modes; @@ -170,60 +170,72 @@ void switch_mode(xcb_connection_t *conn, const char *new_mode) { } /* - * Get the path of the first configuration file found. 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 first, always + * taking into account the XDG Base Directory Specification ($XDG_CONFIG_HOME, + * $XDG_CONFIG_DIRS) * */ -static char *get_config_path() { - char *xdg_config_home, *xdg_config_dirs, *config_path; +static char *get_config_path(const char *override_configpath) { + char *xdg_config_home, *xdg_config_dirs, *config_path; - /* 1: check the traditional path under the home directory */ - config_path = resolve_tilde("~/.i3/config"); - if (path_exists(config_path)) - return config_path; + static const char *saved_configpath = NULL; - /* 2: check for $XDG_CONFIG_HOME/i3/config */ - if ((xdg_config_home = getenv("XDG_CONFIG_HOME")) == NULL) - xdg_config_home = "~/.config"; + if (override_configpath != NULL) { + saved_configpath = override_configpath; + return sstrdup(saved_configpath); + } - xdg_config_home = resolve_tilde(xdg_config_home); - if (asprintf(&config_path, "%s/i3/config", xdg_config_home) == -1) - die("asprintf() failed"); - free(xdg_config_home); + if (saved_configpath != NULL) + return sstrdup(saved_configpath); - if (path_exists(config_path)) - return config_path; - free(config_path); + /* 1: check the traditional path under the home directory */ + config_path = resolve_tilde("~/.i3/config"); + if (path_exists(config_path)) + return config_path; - /* 3: check the traditional path under /etc */ - config_path = SYSCONFDIR "/i3/config"; - if (path_exists(config_path)) - return sstrdup(config_path); + /* 2: check for $XDG_CONFIG_HOME/i3/config */ + if ((xdg_config_home = getenv("XDG_CONFIG_HOME")) == NULL) + xdg_config_home = "~/.config"; - /* 4: check for $XDG_CONFIG_DIRS/i3/config */ - if ((xdg_config_dirs = getenv("XDG_CONFIG_DIRS")) == NULL) - xdg_config_dirs = "/etc/xdg"; + xdg_config_home = resolve_tilde(xdg_config_home); + if (asprintf(&config_path, "%s/i3/config", xdg_config_home) == -1) + die("asprintf() failed"); + free(xdg_config_home); - char *buf = sstrdup(xdg_config_dirs); - char *tok = strtok(buf, ":"); - while (tok != NULL) { - tok = resolve_tilde(tok); - if (asprintf(&config_path, "%s/i3/config", tok) == -1) - die("asprintf() failed"); - free(tok); - if (path_exists(config_path)) { - free(buf); - return config_path; - } - free(config_path); - tok = strtok(NULL, ":"); + if (path_exists(config_path)) + return config_path; + free(config_path); + + /* 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) + xdg_config_dirs = "/etc/xdg"; + + char *buf = sstrdup(xdg_config_dirs); + char *tok = strtok(buf, ":"); + while (tok != NULL) { + tok = resolve_tilde(tok); + if (asprintf(&config_path, "%s/i3/config", tok) == -1) + die("asprintf() failed"); + free(tok); + if (path_exists(config_path)) { + free(buf); + return config_path; } - free(buf); + free(config_path); + tok = strtok(NULL, ":"); + } + free(buf); - 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)"); + 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)"); } /* @@ -233,25 +245,11 @@ static char *get_config_path() { * */ static void parse_configuration(const char *override_configpath) { - static const char *saved_configpath = NULL; - - if (override_configpath != NULL) { - saved_configpath = override_configpath; - current_configpath = override_configpath; - parse_file(override_configpath); - return; - } - else if (saved_configpath != NULL) { - current_configpath = saved_configpath; - parse_file(saved_configpath); - return; - } - - char *path = get_config_path(); + char *path = get_config_path(override_configpath); DLOG("Parsing configfile %s\n", path); + FREE(current_configpath); current_configpath = path; parse_file(path); - free(path); } /* diff --git a/src/main.c b/src/main.c index 309fdaac..2f632dd6 100644 --- a/src/main.c +++ b/src/main.c @@ -351,11 +351,7 @@ int main(int argc, char *argv[]) { xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A__NET_WM_NAME, A_UTF8_STRING, 8, strlen("i3"), "i3"); /* Set up i3 specific atoms like I3_SOCKET_PATH and I3_CONFIG_PATH */ - xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A_I3_SOCKET_PATH, A_UTF8_STRING, 8, - (config.ipc_socket_path != NULL ? strlen(config.ipc_socket_path) : 0), - config.ipc_socket_path); - xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A_I3_CONFIG_PATH, A_UTF8_STRING, 8, - strlen(current_configpath), current_configpath); + x_set_i3_atoms(); keysyms = xcb_key_symbols_alloc(conn); diff --git a/src/x.c b/src/x.c index 188be5fb..8af2e62e 100644 --- a/src/x.c +++ b/src/x.c @@ -703,3 +703,15 @@ void x_set_name(Con *con, const char *name) { FREE(state->name); state->name = sstrdup(name); } + +/* + * Sets up i3 specific atoms (I3_SOCKET_PATH and I3_CONFIG_PATH) + * + */ +void x_set_i3_atoms() { + xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A_I3_SOCKET_PATH, A_UTF8_STRING, 8, + (config.ipc_socket_path != NULL ? strlen(config.ipc_socket_path) : 0), + config.ipc_socket_path); + xcb_change_property(conn, XCB_PROP_MODE_REPLACE, root, A_I3_CONFIG_PATH, A_UTF8_STRING, 8, + strlen(current_configpath), current_configpath); +}