aboutsummaryrefslogtreecommitdiff
path: root/sway
diff options
context:
space:
mode:
Diffstat (limited to 'sway')
-rw-r--r--sway/commands.c7
-rw-r--r--sway/commands/include.c15
-rw-r--r--sway/commands/reload.c19
-rw-r--r--sway/config.c75
-rw-r--r--sway/main.c12
5 files changed, 111 insertions, 17 deletions
diff --git a/sway/commands.c b/sway/commands.c
index fdae1961..81e9ea42 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -511,11 +511,14 @@ struct cmd_results *cmd_results_new(enum cmd_status status,
results->input = NULL;
}
if (format) {
- char *error = malloc(256);
va_list args;
va_start(args, format);
+ size_t length = vsnprintf(NULL, 0, format, args) + 1;
+ char *error = malloc(length);
+ va_end(args);
+ va_start(args, format);
if (error) {
- vsnprintf(error, 256, format, args);
+ vsnprintf(error, length, format, args);
}
va_end(args);
results->error = error;
diff --git a/sway/commands/include.c b/sway/commands/include.c
index 1ba9a10d..72fec7cc 100644
--- a/sway/commands/include.c
+++ b/sway/commands/include.c
@@ -7,8 +7,19 @@ struct cmd_results *cmd_include(int argc, char **argv) {
return error;
}
- if (!load_include_configs(argv[0], config)) {
- return cmd_results_new(CMD_INVALID, "include", "Failed to include sub configuration file: %s", argv[0]);
+ char *errors = NULL;
+ if (!load_include_configs(argv[0], config, &errors)) {
+ struct cmd_results *result = cmd_results_new(CMD_INVALID, "include",
+ "Failed to include sub configuration file: %s", argv[0]);
+ free(errors);
+ return result;
+ }
+
+ if (errors) {
+ struct cmd_results *result = cmd_results_new(CMD_INVALID, "include",
+ "There are errors in the included config\n%s", errors);
+ free(errors);
+ return result;
}
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
diff --git a/sway/commands/reload.c b/sway/commands/reload.c
index 5c1b19b4..9bf671d9 100644
--- a/sway/commands/reload.c
+++ b/sway/commands/reload.c
@@ -1,4 +1,5 @@
#define _XOPEN_SOURCE 500
+#include <signal.h>
#include <string.h>
#include "sway/commands.h"
#include "sway/config.h"
@@ -19,8 +20,11 @@ struct cmd_results *cmd_reload(int argc, char **argv) {
list_add(bar_ids, strdup(bar->id));
}
- if (!load_main_config(config->current_config_path, true)) {
- return cmd_results_new(CMD_FAILURE, "reload", "Error(s) reloading config.");
+ char *errors = NULL;
+ if (!load_main_config(config->current_config_path, true, &errors)) {
+ free(errors);
+ return cmd_results_new(CMD_FAILURE, "reload",
+ "Error(s) reloading config.");
}
ipc_event_workspace(NULL, NULL, "reload");
@@ -42,5 +46,16 @@ struct cmd_results *cmd_reload(int argc, char **argv) {
list_free(bar_ids);
arrange_windows(&root_container);
+
+ if (config->swaynag_pid > 0) {
+ kill(config->swaynag_pid, SIGTERM);
+ config->swaynag_pid = -1;
+ }
+
+ if (errors) {
+ spawn_swaynag_config_errors(config, errors);
+ free(errors);
+ }
+
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
}
diff --git a/sway/config.c b/sway/config.c
index 2afffab1..bd282541 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -158,6 +158,7 @@ static void set_color(float dest[static 4], uint32_t color) {
}
static void config_defaults(struct sway_config *config) {
+ config->swaynag_pid = -1;
if (!(config->symbols = create_list())) goto cleanup;
if (!(config->modes = create_list())) goto cleanup;
if (!(config->bars = create_list())) goto cleanup;
@@ -319,7 +320,8 @@ static char *get_config_path(void) {
return NULL; // Not reached
}
-static bool load_config(const char *path, struct sway_config *config) {
+static bool load_config(const char *path, struct sway_config *config,
+ char **errors) {
if (path == NULL) {
wlr_log(WLR_ERROR, "Unable to find a config file!");
return false;
@@ -338,7 +340,7 @@ static bool load_config(const char *path, struct sway_config *config) {
return false;
}
- bool config_load_success = read_config(f, config);
+ bool config_load_success = read_config(f, config, errors);
fclose(f);
if (!config_load_success) {
@@ -348,7 +350,7 @@ static bool load_config(const char *path, struct sway_config *config) {
return true;
}
-bool load_main_config(const char *file, bool is_active) {
+bool load_main_config(const char *file, bool is_active, char **errors) {
char *path;
if (file != NULL) {
path = strdup(file);
@@ -365,6 +367,7 @@ bool load_main_config(const char *file, bool is_active) {
config_defaults(config);
if (is_active) {
wlr_log(WLR_DEBUG, "Performing configuration file reload");
+ config->swaynag_pid = old_config->swaynag_pid;
config->reloading = true;
config->active = true;
create_default_output_configs();
@@ -423,7 +426,7 @@ bool load_main_config(const char *file, bool is_active) {
}
*/
- success = success && load_config(path, config);
+ success = success && load_config(path, config, errors);
if (is_active) {
for (int i = 0; i < config->output_configs->length; i++) {
@@ -441,7 +444,7 @@ bool load_main_config(const char *file, bool is_active) {
}
static bool load_include_config(const char *path, const char *parent_dir,
- struct sway_config *config) {
+ struct sway_config *config, char **errors) {
// save parent config
const char *parent_config = config->current_config_path;
@@ -485,7 +488,7 @@ static bool load_include_config(const char *path, const char *parent_dir,
list_add(config->config_chain, real_path);
int index = config->config_chain->length - 1;
- if (!load_config(real_path, config)) {
+ if (!load_config(real_path, config, errors)) {
free(real_path);
config->current_config_path = parent_config;
list_del(config->config_chain, index);
@@ -497,7 +500,8 @@ static bool load_include_config(const char *path, const char *parent_dir,
return true;
}
-bool load_include_configs(const char *path, struct sway_config *config) {
+bool load_include_configs(const char *path, struct sway_config *config,
+ char **errors) {
char *wd = getcwd(NULL, 0);
char *parent_path = strdup(config->current_config_path);
const char *parent_dir = dirname(parent_path);
@@ -519,7 +523,7 @@ bool load_include_configs(const char *path, struct sway_config *config) {
char **w = p.we_wordv;
size_t i;
for (i = 0; i < p.we_wordc; ++i) {
- load_include_config(w[i], parent_dir, config);
+ load_include_config(w[i], parent_dir, config, errors);
}
free(parent_path);
wordfree(&p);
@@ -575,7 +579,26 @@ static char *expand_line(const char *block, const char *line, bool add_brace) {
return expanded;
}
-bool read_config(FILE *file, struct sway_config *config) {
+static void log_error(char **errors, const char *fmt, ...) {
+ va_list args;
+ va_start(args, fmt);
+ size_t length = vsnprintf(NULL, 0, fmt, args) + 1;
+ va_end(args);
+
+ int offset = *errors ? strlen(*errors) : 0;
+ char *temp = realloc(*errors, offset + length + 1);
+ if (!temp) {
+ wlr_log(WLR_ERROR, "Failed to realloc error log");
+ return;
+ }
+ *errors = temp;
+
+ va_start(args, fmt);
+ vsnprintf(*errors + offset, length, fmt, args);
+ va_end(args);
+}
+
+bool read_config(FILE *file, struct sway_config *config, char **errors) {
bool reading_main_config = false;
char *this_config = NULL;
size_t config_size = 0;
@@ -665,6 +688,8 @@ bool read_config(FILE *file, struct sway_config *config) {
case CMD_INVALID:
wlr_log(WLR_ERROR, "Error on line %i '%s': %s (%s)", line_number,
line, res->error, config->current_config_path);
+ log_error(errors, "Error on line %i (%s) '%s': %s\n", line_number,
+ config->current_config_path, line, res->error);
success = false;
break;
@@ -713,6 +738,38 @@ bool read_config(FILE *file, struct sway_config *config) {
return success;
}
+void spawn_swaynag_config_errors(struct sway_config *config, char *errors) {
+ char *command = "swaynag "
+ "--type error "
+ "--message 'There are errors in your config file' "
+ "--detailed-message "
+ "--button 'Exit sway' 'swaymsg exit' "
+ "--button 'Reload sway' 'swaymsg reload'";
+
+ int fd[2];
+ if (pipe(fd) != 0) {
+ wlr_log(WLR_ERROR, "Failed to create pipe for swaynag");
+ return;
+ }
+
+ pid_t pid;
+ if ((pid = fork()) == 0) {
+ close(fd[1]);
+ dup2(fd[0], STDIN_FILENO);
+ close(fd[0]);
+ execl("/bin/sh", "/bin/sh", "-c", command, NULL);
+ _exit(0);
+ } else if (pid < 0) {
+ wlr_log(WLR_ERROR, "Failed to create fork for swaynag");
+ }
+
+ close(fd[0]);
+ write(fd[1], errors, strlen(errors));
+ close(fd[1]);
+
+ config->swaynag_pid = pid;
+}
+
char *do_var_replacement(char *str) {
int i;
char *find = str;
diff --git a/sway/main.c b/sway/main.c
index 477ffa5a..de2445a8 100644
--- a/sway/main.c
+++ b/sway/main.c
@@ -415,12 +415,14 @@ int main(int argc, char **argv) {
ipc_init(&server);
log_env();
+ char *errors = NULL;
if (validate) {
- bool valid = load_main_config(config_path, false);
+ bool valid = load_main_config(config_path, false, &errors);
+ free(errors);
return valid ? 0 : 1;
}
- if (!load_main_config(config_path, false)) {
+ if (!load_main_config(config_path, false, &errors)) {
sway_terminate(EXIT_FAILURE);
}
@@ -433,6 +435,7 @@ int main(int argc, char **argv) {
setenv("WAYLAND_DISPLAY", server.socket, true);
if (!terminate_request) {
if (!server_start_backend(&server)) {
+ free(errors);
sway_terminate(EXIT_FAILURE);
}
}
@@ -452,6 +455,11 @@ int main(int argc, char **argv) {
}
transaction_commit_dirty();
+ if (errors) {
+ spawn_swaynag_config_errors(config, errors);
+ free(errors);
+ }
+
if (!terminate_request) {
server_run(&server);
}