diff options
author | Brian Ashworth <bosrsf04@gmail.com> | 2018-08-01 23:54:40 -0400 |
---|---|---|
committer | Brian Ashworth <bosrsf04@gmail.com> | 2018-08-03 10:37:35 -0400 |
commit | f9a6407111a8730df51258c3b07502814a8ab3e1 (patch) | |
tree | 6cf180159caf4a45a8f37b026b2769d24468a07b /sway | |
parent | Merge pull request #2417 from marienz/swaynag-includes (diff) | |
download | sway-f9a6407111a8730df51258c3b07502814a8ab3e1.tar.gz sway-f9a6407111a8730df51258c3b07502814a8ab3e1.tar.zst sway-f9a6407111a8730df51258c3b07502814a8ab3e1.zip |
Show swaynag on config errors
Diffstat (limited to 'sway')
-rw-r--r-- | sway/commands.c | 7 | ||||
-rw-r--r-- | sway/commands/include.c | 15 | ||||
-rw-r--r-- | sway/commands/reload.c | 19 | ||||
-rw-r--r-- | sway/config.c | 75 | ||||
-rw-r--r-- | sway/main.c | 12 |
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, | |||
511 | results->input = NULL; | 511 | results->input = NULL; |
512 | } | 512 | } |
513 | if (format) { | 513 | if (format) { |
514 | char *error = malloc(256); | ||
515 | va_list args; | 514 | va_list args; |
516 | va_start(args, format); | 515 | va_start(args, format); |
516 | size_t length = vsnprintf(NULL, 0, format, args) + 1; | ||
517 | char *error = malloc(length); | ||
518 | va_end(args); | ||
519 | va_start(args, format); | ||
517 | if (error) { | 520 | if (error) { |
518 | vsnprintf(error, 256, format, args); | 521 | vsnprintf(error, length, format, args); |
519 | } | 522 | } |
520 | va_end(args); | 523 | va_end(args); |
521 | results->error = error; | 524 | 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) { | |||
7 | return error; | 7 | return error; |
8 | } | 8 | } |
9 | 9 | ||
10 | if (!load_include_configs(argv[0], config)) { | 10 | char *errors = NULL; |
11 | return cmd_results_new(CMD_INVALID, "include", "Failed to include sub configuration file: %s", argv[0]); | 11 | if (!load_include_configs(argv[0], config, &errors)) { |
12 | struct cmd_results *result = cmd_results_new(CMD_INVALID, "include", | ||
13 | "Failed to include sub configuration file: %s", argv[0]); | ||
14 | free(errors); | ||
15 | return result; | ||
16 | } | ||
17 | |||
18 | if (errors) { | ||
19 | struct cmd_results *result = cmd_results_new(CMD_INVALID, "include", | ||
20 | "There are errors in the included config\n%s", errors); | ||
21 | free(errors); | ||
22 | return result; | ||
12 | } | 23 | } |
13 | 24 | ||
14 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 25 | 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 @@ | |||
1 | #define _XOPEN_SOURCE 500 | 1 | #define _XOPEN_SOURCE 500 |
2 | #include <signal.h> | ||
2 | #include <string.h> | 3 | #include <string.h> |
3 | #include "sway/commands.h" | 4 | #include "sway/commands.h" |
4 | #include "sway/config.h" | 5 | #include "sway/config.h" |
@@ -19,8 +20,11 @@ struct cmd_results *cmd_reload(int argc, char **argv) { | |||
19 | list_add(bar_ids, strdup(bar->id)); | 20 | list_add(bar_ids, strdup(bar->id)); |
20 | } | 21 | } |
21 | 22 | ||
22 | if (!load_main_config(config->current_config_path, true)) { | 23 | char *errors = NULL; |
23 | return cmd_results_new(CMD_FAILURE, "reload", "Error(s) reloading config."); | 24 | if (!load_main_config(config->current_config_path, true, &errors)) { |
25 | free(errors); | ||
26 | return cmd_results_new(CMD_FAILURE, "reload", | ||
27 | "Error(s) reloading config."); | ||
24 | } | 28 | } |
25 | ipc_event_workspace(NULL, NULL, "reload"); | 29 | ipc_event_workspace(NULL, NULL, "reload"); |
26 | 30 | ||
@@ -42,5 +46,16 @@ struct cmd_results *cmd_reload(int argc, char **argv) { | |||
42 | list_free(bar_ids); | 46 | list_free(bar_ids); |
43 | 47 | ||
44 | arrange_windows(&root_container); | 48 | arrange_windows(&root_container); |
49 | |||
50 | if (config->swaynag_pid > 0) { | ||
51 | kill(config->swaynag_pid, SIGTERM); | ||
52 | config->swaynag_pid = -1; | ||
53 | } | ||
54 | |||
55 | if (errors) { | ||
56 | spawn_swaynag_config_errors(config, errors); | ||
57 | free(errors); | ||
58 | } | ||
59 | |||
45 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); | 60 | return cmd_results_new(CMD_SUCCESS, NULL, NULL); |
46 | } | 61 | } |
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) { | |||
158 | } | 158 | } |
159 | 159 | ||
160 | static void config_defaults(struct sway_config *config) { | 160 | static void config_defaults(struct sway_config *config) { |
161 | config->swaynag_pid = -1; | ||
161 | if (!(config->symbols = create_list())) goto cleanup; | 162 | if (!(config->symbols = create_list())) goto cleanup; |
162 | if (!(config->modes = create_list())) goto cleanup; | 163 | if (!(config->modes = create_list())) goto cleanup; |
163 | if (!(config->bars = create_list())) goto cleanup; | 164 | if (!(config->bars = create_list())) goto cleanup; |
@@ -319,7 +320,8 @@ static char *get_config_path(void) { | |||
319 | return NULL; // Not reached | 320 | return NULL; // Not reached |
320 | } | 321 | } |
321 | 322 | ||
322 | static bool load_config(const char *path, struct sway_config *config) { | 323 | static bool load_config(const char *path, struct sway_config *config, |
324 | char **errors) { | ||
323 | if (path == NULL) { | 325 | if (path == NULL) { |
324 | wlr_log(WLR_ERROR, "Unable to find a config file!"); | 326 | wlr_log(WLR_ERROR, "Unable to find a config file!"); |
325 | return false; | 327 | return false; |
@@ -338,7 +340,7 @@ static bool load_config(const char *path, struct sway_config *config) { | |||
338 | return false; | 340 | return false; |
339 | } | 341 | } |
340 | 342 | ||
341 | bool config_load_success = read_config(f, config); | 343 | bool config_load_success = read_config(f, config, errors); |
342 | fclose(f); | 344 | fclose(f); |
343 | 345 | ||
344 | if (!config_load_success) { | 346 | if (!config_load_success) { |
@@ -348,7 +350,7 @@ static bool load_config(const char *path, struct sway_config *config) { | |||
348 | return true; | 350 | return true; |
349 | } | 351 | } |
350 | 352 | ||
351 | bool load_main_config(const char *file, bool is_active) { | 353 | bool load_main_config(const char *file, bool is_active, char **errors) { |
352 | char *path; | 354 | char *path; |
353 | if (file != NULL) { | 355 | if (file != NULL) { |
354 | path = strdup(file); | 356 | path = strdup(file); |
@@ -365,6 +367,7 @@ bool load_main_config(const char *file, bool is_active) { | |||
365 | config_defaults(config); | 367 | config_defaults(config); |
366 | if (is_active) { | 368 | if (is_active) { |
367 | wlr_log(WLR_DEBUG, "Performing configuration file reload"); | 369 | wlr_log(WLR_DEBUG, "Performing configuration file reload"); |
370 | config->swaynag_pid = old_config->swaynag_pid; | ||
368 | config->reloading = true; | 371 | config->reloading = true; |
369 | config->active = true; | 372 | config->active = true; |
370 | create_default_output_configs(); | 373 | create_default_output_configs(); |
@@ -423,7 +426,7 @@ bool load_main_config(const char *file, bool is_active) { | |||
423 | } | 426 | } |
424 | */ | 427 | */ |
425 | 428 | ||
426 | success = success && load_config(path, config); | 429 | success = success && load_config(path, config, errors); |
427 | 430 | ||
428 | if (is_active) { | 431 | if (is_active) { |
429 | for (int i = 0; i < config->output_configs->length; i++) { | 432 | for (int i = 0; i < config->output_configs->length; i++) { |
@@ -441,7 +444,7 @@ bool load_main_config(const char *file, bool is_active) { | |||
441 | } | 444 | } |
442 | 445 | ||
443 | static bool load_include_config(const char *path, const char *parent_dir, | 446 | static bool load_include_config(const char *path, const char *parent_dir, |
444 | struct sway_config *config) { | 447 | struct sway_config *config, char **errors) { |
445 | // save parent config | 448 | // save parent config |
446 | const char *parent_config = config->current_config_path; | 449 | const char *parent_config = config->current_config_path; |
447 | 450 | ||
@@ -485,7 +488,7 @@ static bool load_include_config(const char *path, const char *parent_dir, | |||
485 | list_add(config->config_chain, real_path); | 488 | list_add(config->config_chain, real_path); |
486 | int index = config->config_chain->length - 1; | 489 | int index = config->config_chain->length - 1; |
487 | 490 | ||
488 | if (!load_config(real_path, config)) { | 491 | if (!load_config(real_path, config, errors)) { |
489 | free(real_path); | 492 | free(real_path); |
490 | config->current_config_path = parent_config; | 493 | config->current_config_path = parent_config; |
491 | list_del(config->config_chain, index); | 494 | list_del(config->config_chain, index); |
@@ -497,7 +500,8 @@ static bool load_include_config(const char *path, const char *parent_dir, | |||
497 | return true; | 500 | return true; |
498 | } | 501 | } |
499 | 502 | ||
500 | bool load_include_configs(const char *path, struct sway_config *config) { | 503 | bool load_include_configs(const char *path, struct sway_config *config, |
504 | char **errors) { | ||
501 | char *wd = getcwd(NULL, 0); | 505 | char *wd = getcwd(NULL, 0); |
502 | char *parent_path = strdup(config->current_config_path); | 506 | char *parent_path = strdup(config->current_config_path); |
503 | const char *parent_dir = dirname(parent_path); | 507 | const char *parent_dir = dirname(parent_path); |
@@ -519,7 +523,7 @@ bool load_include_configs(const char *path, struct sway_config *config) { | |||
519 | char **w = p.we_wordv; | 523 | char **w = p.we_wordv; |
520 | size_t i; | 524 | size_t i; |
521 | for (i = 0; i < p.we_wordc; ++i) { | 525 | for (i = 0; i < p.we_wordc; ++i) { |
522 | load_include_config(w[i], parent_dir, config); | 526 | load_include_config(w[i], parent_dir, config, errors); |
523 | } | 527 | } |
524 | free(parent_path); | 528 | free(parent_path); |
525 | wordfree(&p); | 529 | wordfree(&p); |
@@ -575,7 +579,26 @@ static char *expand_line(const char *block, const char *line, bool add_brace) { | |||
575 | return expanded; | 579 | return expanded; |
576 | } | 580 | } |
577 | 581 | ||
578 | bool read_config(FILE *file, struct sway_config *config) { | 582 | static void log_error(char **errors, const char *fmt, ...) { |
583 | va_list args; | ||
584 | va_start(args, fmt); | ||
585 | size_t length = vsnprintf(NULL, 0, fmt, args) + 1; | ||
586 | va_end(args); | ||
587 | |||
588 | int offset = *errors ? strlen(*errors) : 0; | ||
589 | char *temp = realloc(*errors, offset + length + 1); | ||
590 | if (!temp) { | ||
591 | wlr_log(WLR_ERROR, "Failed to realloc error log"); | ||
592 | return; | ||
593 | } | ||
594 | *errors = temp; | ||
595 | |||
596 | va_start(args, fmt); | ||
597 | vsnprintf(*errors + offset, length, fmt, args); | ||
598 | va_end(args); | ||
599 | } | ||
600 | |||
601 | bool read_config(FILE *file, struct sway_config *config, char **errors) { | ||
579 | bool reading_main_config = false; | 602 | bool reading_main_config = false; |
580 | char *this_config = NULL; | 603 | char *this_config = NULL; |
581 | size_t config_size = 0; | 604 | size_t config_size = 0; |
@@ -665,6 +688,8 @@ bool read_config(FILE *file, struct sway_config *config) { | |||
665 | case CMD_INVALID: | 688 | case CMD_INVALID: |
666 | wlr_log(WLR_ERROR, "Error on line %i '%s': %s (%s)", line_number, | 689 | wlr_log(WLR_ERROR, "Error on line %i '%s': %s (%s)", line_number, |
667 | line, res->error, config->current_config_path); | 690 | line, res->error, config->current_config_path); |
691 | log_error(errors, "Error on line %i (%s) '%s': %s\n", line_number, | ||
692 | config->current_config_path, line, res->error); | ||
668 | success = false; | 693 | success = false; |
669 | break; | 694 | break; |
670 | 695 | ||
@@ -713,6 +738,38 @@ bool read_config(FILE *file, struct sway_config *config) { | |||
713 | return success; | 738 | return success; |
714 | } | 739 | } |
715 | 740 | ||
741 | void spawn_swaynag_config_errors(struct sway_config *config, char *errors) { | ||
742 | char *command = "swaynag " | ||
743 | "--type error " | ||
744 | "--message 'There are errors in your config file' " | ||
745 | "--detailed-message " | ||
746 | "--button 'Exit sway' 'swaymsg exit' " | ||
747 | "--button 'Reload sway' 'swaymsg reload'"; | ||
748 | |||
749 | int fd[2]; | ||
750 | if (pipe(fd) != 0) { | ||
751 | wlr_log(WLR_ERROR, "Failed to create pipe for swaynag"); | ||
752 | return; | ||
753 | } | ||
754 | |||
755 | pid_t pid; | ||
756 | if ((pid = fork()) == 0) { | ||
757 | close(fd[1]); | ||
758 | dup2(fd[0], STDIN_FILENO); | ||
759 | close(fd[0]); | ||
760 | execl("/bin/sh", "/bin/sh", "-c", command, NULL); | ||
761 | _exit(0); | ||
762 | } else if (pid < 0) { | ||
763 | wlr_log(WLR_ERROR, "Failed to create fork for swaynag"); | ||
764 | } | ||
765 | |||
766 | close(fd[0]); | ||
767 | write(fd[1], errors, strlen(errors)); | ||
768 | close(fd[1]); | ||
769 | |||
770 | config->swaynag_pid = pid; | ||
771 | } | ||
772 | |||
716 | char *do_var_replacement(char *str) { | 773 | char *do_var_replacement(char *str) { |
717 | int i; | 774 | int i; |
718 | char *find = str; | 775 | 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) { | |||
415 | ipc_init(&server); | 415 | ipc_init(&server); |
416 | log_env(); | 416 | log_env(); |
417 | 417 | ||
418 | char *errors = NULL; | ||
418 | if (validate) { | 419 | if (validate) { |
419 | bool valid = load_main_config(config_path, false); | 420 | bool valid = load_main_config(config_path, false, &errors); |
421 | free(errors); | ||
420 | return valid ? 0 : 1; | 422 | return valid ? 0 : 1; |
421 | } | 423 | } |
422 | 424 | ||
423 | if (!load_main_config(config_path, false)) { | 425 | if (!load_main_config(config_path, false, &errors)) { |
424 | sway_terminate(EXIT_FAILURE); | 426 | sway_terminate(EXIT_FAILURE); |
425 | } | 427 | } |
426 | 428 | ||
@@ -433,6 +435,7 @@ int main(int argc, char **argv) { | |||
433 | setenv("WAYLAND_DISPLAY", server.socket, true); | 435 | setenv("WAYLAND_DISPLAY", server.socket, true); |
434 | if (!terminate_request) { | 436 | if (!terminate_request) { |
435 | if (!server_start_backend(&server)) { | 437 | if (!server_start_backend(&server)) { |
438 | free(errors); | ||
436 | sway_terminate(EXIT_FAILURE); | 439 | sway_terminate(EXIT_FAILURE); |
437 | } | 440 | } |
438 | } | 441 | } |
@@ -452,6 +455,11 @@ int main(int argc, char **argv) { | |||
452 | } | 455 | } |
453 | transaction_commit_dirty(); | 456 | transaction_commit_dirty(); |
454 | 457 | ||
458 | if (errors) { | ||
459 | spawn_swaynag_config_errors(config, errors); | ||
460 | free(errors); | ||
461 | } | ||
462 | |||
455 | if (!terminate_request) { | 463 | if (!terminate_request) { |
456 | server_run(&server); | 464 | server_run(&server); |
457 | } | 465 | } |