summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2018-08-03 15:08:38 -0400
committerLibravatar GitHub <noreply@github.com>2018-08-03 15:08:38 -0400
commit38675eba7be471a2dacb5928f54d046297c23517 (patch)
tree7982d1f38fcb3620372c1c8461de1450063e5355
parentMerge pull request #2417 from marienz/swaynag-includes (diff)
parentRemove swaynag_clone and use memcpy (diff)
downloadsway-38675eba7be471a2dacb5928f54d046297c23517.tar.gz
sway-38675eba7be471a2dacb5928f54d046297c23517.tar.zst
sway-38675eba7be471a2dacb5928f54d046297c23517.zip
Merge pull request #2400 from RedSoxFan/swaynag-config-errors
Show swaynag on config errors
-rw-r--r--include/sway/commands.h1
-rw-r--r--include/sway/config.h12
-rw-r--r--include/sway/swaynag.h29
-rw-r--r--sway/commands.c1
-rw-r--r--sway/commands/include.c6
-rw-r--r--sway/commands/reload.c6
-rw-r--r--sway/commands/swaynag_command.c20
-rw-r--r--sway/config.c52
-rw-r--r--sway/main.c11
-rw-r--r--sway/meson.build2
-rw-r--r--sway/sway.5.scd7
-rw-r--r--sway/swaynag.c94
12 files changed, 222 insertions, 19 deletions
diff --git a/include/sway/commands.h b/include/sway/commands.h
index 41858ccc..f83907b2 100644
--- a/include/sway/commands.h
+++ b/include/sway/commands.h
@@ -150,6 +150,7 @@ sway_cmd cmd_splitt;
150sway_cmd cmd_splitv; 150sway_cmd cmd_splitv;
151sway_cmd cmd_sticky; 151sway_cmd cmd_sticky;
152sway_cmd cmd_swaybg_command; 152sway_cmd cmd_swaybg_command;
153sway_cmd cmd_swaynag_command;
153sway_cmd cmd_swap; 154sway_cmd cmd_swap;
154sway_cmd cmd_title_format; 155sway_cmd cmd_title_format;
155sway_cmd cmd_unmark; 156sway_cmd cmd_unmark;
diff --git a/include/sway/config.h b/include/sway/config.h
index 909b6827..632aca14 100644
--- a/include/sway/config.h
+++ b/include/sway/config.h
@@ -7,6 +7,7 @@
7#include <wlr/types/wlr_box.h> 7#include <wlr/types/wlr_box.h>
8#include <xkbcommon/xkbcommon.h> 8#include <xkbcommon/xkbcommon.h>
9#include "list.h" 9#include "list.h"
10#include "swaynag.h"
10#include "tree/layout.h" 11#include "tree/layout.h"
11#include "tree/container.h" 12#include "tree/container.h"
12#include "wlr-layer-shell-unstable-v1-protocol.h" 13#include "wlr-layer-shell-unstable-v1-protocol.h"
@@ -308,6 +309,8 @@ enum focus_wrapping_mode {
308 * The configuration struct. The result of loading a config file. 309 * The configuration struct. The result of loading a config file.
309 */ 310 */
310struct sway_config { 311struct sway_config {
312 char *swaynag_command;
313 struct swaynag_instance swaynag_config_errors;
311 list_t *symbols; 314 list_t *symbols;
312 list_t *modes; 315 list_t *modes;
313 list_t *bars; 316 list_t *bars;
@@ -345,6 +348,7 @@ struct sway_config {
345 bool failed; 348 bool failed;
346 bool reloading; 349 bool reloading;
347 bool reading; 350 bool reading;
351 bool validating;
348 bool auto_back_and_forth; 352 bool auto_back_and_forth;
349 bool show_marks; 353 bool show_marks;
350 354
@@ -403,17 +407,19 @@ struct sway_config {
403 * Loads the main config from the given path. is_active should be true when 407 * Loads the main config from the given path. is_active should be true when
404 * reloading the config. 408 * reloading the config.
405 */ 409 */
406bool load_main_config(const char *path, bool is_active); 410bool load_main_config(const char *path, bool is_active, bool validating);
407 411
408/** 412/**
409 * Loads an included config. Can only be used after load_main_config. 413 * Loads an included config. Can only be used after load_main_config.
410 */ 414 */
411bool load_include_configs(const char *path, struct sway_config *config); 415bool load_include_configs(const char *path, struct sway_config *config,
416 struct swaynag_instance *swaynag);
412 417
413/** 418/**
414 * Reads the config from the given FILE. 419 * Reads the config from the given FILE.
415 */ 420 */
416bool read_config(FILE *file, struct sway_config *config); 421bool read_config(FILE *file, struct sway_config *config,
422 struct swaynag_instance *swaynag);
417 423
418/** 424/**
419 * Free config struct 425 * Free config struct
diff --git a/include/sway/swaynag.h b/include/sway/swaynag.h
new file mode 100644
index 00000000..5a178739
--- /dev/null
+++ b/include/sway/swaynag.h
@@ -0,0 +1,29 @@
1#ifndef _SWAY_SWAYNAG_H
2#define _SWAY_SWAYNAG_H
3
4struct swaynag_instance {
5 const char *args;
6 pid_t pid;
7 int fd[2];
8 bool detailed;
9};
10
11// Spawn swaynag. If swaynag->detailed, then swaynag->fd[1] will left open
12// so it can be written to. Call swaynag_show when done writing. This will
13// be automatically called by swaynag_log if the instance is not spawned and
14// swaynag->detailed is true.
15bool swaynag_spawn(const char *swaynag_command,
16 struct swaynag_instance *swaynag);
17
18// Kill the swaynag instance
19void swaynag_kill(struct swaynag_instance *swaynag);
20
21// Write a log message to swaynag->fd[1]. This will fail when swaynag->detailed
22// is false.
23void swaynag_log(const char *swaynag_command, struct swaynag_instance *swaynag,
24 const char *fmt, ...);
25
26// If swaynag->detailed, close swaynag->fd[1] so swaynag displays
27void swaynag_show(struct swaynag_instance *swaynag);
28
29#endif
diff --git a/sway/commands.c b/sway/commands.c
index fdae1961..364c26da 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -132,6 +132,7 @@ static struct cmd_handler handlers[] = {
132static struct cmd_handler config_handlers[] = { 132static struct cmd_handler config_handlers[] = {
133 { "default_orientation", cmd_default_orientation }, 133 { "default_orientation", cmd_default_orientation },
134 { "swaybg_command", cmd_swaybg_command }, 134 { "swaybg_command", cmd_swaybg_command },
135 { "swaynag_command", cmd_swaynag_command },
135 { "workspace_layout", cmd_workspace_layout }, 136 { "workspace_layout", cmd_workspace_layout },
136}; 137};
137 138
diff --git a/sway/commands/include.c b/sway/commands/include.c
index 1ba9a10d..61f383bb 100644
--- a/sway/commands/include.c
+++ b/sway/commands/include.c
@@ -7,8 +7,10 @@ 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 if (!load_include_configs(argv[0], config,
11 return cmd_results_new(CMD_INVALID, "include", "Failed to include sub configuration file: %s", argv[0]); 11 &config->swaynag_config_errors)) {
12 return cmd_results_new(CMD_INVALID, "include",
13 "Failed to include sub configuration file: %s", argv[0]);
12 } 14 }
13 15
14 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 16 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
diff --git a/sway/commands/reload.c b/sway/commands/reload.c
index 5c1b19b4..f8ca374d 100644
--- a/sway/commands/reload.c
+++ b/sway/commands/reload.c
@@ -19,8 +19,9 @@ struct cmd_results *cmd_reload(int argc, char **argv) {
19 list_add(bar_ids, strdup(bar->id)); 19 list_add(bar_ids, strdup(bar->id));
20 } 20 }
21 21
22 if (!load_main_config(config->current_config_path, true)) { 22 if (!load_main_config(config->current_config_path, true, false)) {
23 return cmd_results_new(CMD_FAILURE, "reload", "Error(s) reloading config."); 23 return cmd_results_new(CMD_FAILURE, "reload",
24 "Error(s) reloading config.");
24 } 25 }
25 ipc_event_workspace(NULL, NULL, "reload"); 26 ipc_event_workspace(NULL, NULL, "reload");
26 27
@@ -42,5 +43,6 @@ struct cmd_results *cmd_reload(int argc, char **argv) {
42 list_free(bar_ids); 43 list_free(bar_ids);
43 44
44 arrange_windows(&root_container); 45 arrange_windows(&root_container);
46
45 return cmd_results_new(CMD_SUCCESS, NULL, NULL); 47 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
46} 48}
diff --git a/sway/commands/swaynag_command.c b/sway/commands/swaynag_command.c
new file mode 100644
index 00000000..c57a80a6
--- /dev/null
+++ b/sway/commands/swaynag_command.c
@@ -0,0 +1,20 @@
1#include <string.h>
2#include "sway/commands.h"
3#include "log.h"
4#include "stringop.h"
5
6struct cmd_results *cmd_swaynag_command(int argc, char **argv) {
7 struct cmd_results *error = NULL;
8 if ((error = checkarg(argc, "swaynag_command", EXPECTED_AT_LEAST, 1))) {
9 return error;
10 }
11
12 if (config->swaynag_command) {
13 free(config->swaynag_command);
14 }
15 config->swaynag_command = join_args(argv, argc);
16 wlr_log(WLR_DEBUG, "Using custom swaynag command: %s",
17 config->swaynag_command);
18
19 return cmd_results_new(CMD_SUCCESS, NULL, NULL);
20}
diff --git a/sway/config.c b/sway/config.c
index 2afffab1..c1ec77f9 100644
--- a/sway/config.c
+++ b/sway/config.c
@@ -25,6 +25,7 @@
25#include "sway/commands.h" 25#include "sway/commands.h"
26#include "sway/config.h" 26#include "sway/config.h"
27#include "sway/criteria.h" 27#include "sway/criteria.h"
28#include "sway/swaynag.h"
28#include "sway/tree/arrange.h" 29#include "sway/tree/arrange.h"
29#include "sway/tree/layout.h" 30#include "sway/tree/layout.h"
30#include "sway/tree/workspace.h" 31#include "sway/tree/workspace.h"
@@ -72,6 +73,8 @@ void free_config(struct sway_config *config) {
72 73
73 memset(&config->handler_context, 0, sizeof(config->handler_context)); 74 memset(&config->handler_context, 0, sizeof(config->handler_context));
74 75
76 free(config->swaynag_command);
77
75 // TODO: handle all currently unhandled lists as we add implementations 78 // TODO: handle all currently unhandled lists as we add implementations
76 if (config->symbols) { 79 if (config->symbols) {
77 for (int i = 0; i < config->symbols->length; ++i) { 80 for (int i = 0; i < config->symbols->length; ++i) {
@@ -158,6 +161,17 @@ static void set_color(float dest[static 4], uint32_t color) {
158} 161}
159 162
160static void config_defaults(struct sway_config *config) { 163static void config_defaults(struct sway_config *config) {
164 config->swaynag_command = strdup("swaynag");
165 config->swaynag_config_errors = (struct swaynag_instance){
166 .args = "--type error "
167 "--message 'There are errors in your config file' "
168 "--detailed-message "
169 "--button 'Exit sway' 'swaymsg exit' "
170 "--button 'Reload sway' 'swaymsg reload'",
171 .pid = -1,
172 .detailed = true,
173 };
174
161 if (!(config->symbols = create_list())) goto cleanup; 175 if (!(config->symbols = create_list())) goto cleanup;
162 if (!(config->modes = create_list())) goto cleanup; 176 if (!(config->modes = create_list())) goto cleanup;
163 if (!(config->bars = create_list())) goto cleanup; 177 if (!(config->bars = create_list())) goto cleanup;
@@ -204,6 +218,7 @@ static void config_defaults(struct sway_config *config) {
204 config->focus_follows_mouse = true; 218 config->focus_follows_mouse = true;
205 config->mouse_warping = true; 219 config->mouse_warping = true;
206 config->focus_wrapping = WRAP_YES; 220 config->focus_wrapping = WRAP_YES;
221 config->validating = false;
207 config->reloading = false; 222 config->reloading = false;
208 config->active = false; 223 config->active = false;
209 config->failed = false; 224 config->failed = false;
@@ -319,7 +334,8 @@ static char *get_config_path(void) {
319 return NULL; // Not reached 334 return NULL; // Not reached
320} 335}
321 336
322static bool load_config(const char *path, struct sway_config *config) { 337static bool load_config(const char *path, struct sway_config *config,
338 struct swaynag_instance *swaynag) {
323 if (path == NULL) { 339 if (path == NULL) {
324 wlr_log(WLR_ERROR, "Unable to find a config file!"); 340 wlr_log(WLR_ERROR, "Unable to find a config file!");
325 return false; 341 return false;
@@ -338,7 +354,7 @@ static bool load_config(const char *path, struct sway_config *config) {
338 return false; 354 return false;
339 } 355 }
340 356
341 bool config_load_success = read_config(f, config); 357 bool config_load_success = read_config(f, config, swaynag);
342 fclose(f); 358 fclose(f);
343 359
344 if (!config_load_success) { 360 if (!config_load_success) {
@@ -348,7 +364,7 @@ static bool load_config(const char *path, struct sway_config *config) {
348 return true; 364 return true;
349} 365}
350 366
351bool load_main_config(const char *file, bool is_active) { 367bool load_main_config(const char *file, bool is_active, bool validating) {
352 char *path; 368 char *path;
353 if (file != NULL) { 369 if (file != NULL) {
354 path = strdup(file); 370 path = strdup(file);
@@ -363,10 +379,17 @@ bool load_main_config(const char *file, bool is_active) {
363 } 379 }
364 380
365 config_defaults(config); 381 config_defaults(config);
382 config->validating = validating;
366 if (is_active) { 383 if (is_active) {
367 wlr_log(WLR_DEBUG, "Performing configuration file reload"); 384 wlr_log(WLR_DEBUG, "Performing configuration file reload");
368 config->reloading = true; 385 config->reloading = true;
369 config->active = true; 386 config->active = true;
387
388 swaynag_kill(&old_config->swaynag_config_errors);
389 memcpy(&config->swaynag_config_errors,
390 &old_config->swaynag_config_errors,
391 sizeof(struct swaynag_instance));
392
370 create_default_output_configs(); 393 create_default_output_configs();
371 } 394 }
372 395
@@ -423,13 +446,17 @@ bool load_main_config(const char *file, bool is_active) {
423 } 446 }
424 */ 447 */
425 448
426 success = success && load_config(path, config); 449 success = success && load_config(path, config,
450 &config->swaynag_config_errors);
427 451
428 if (is_active) { 452 if (is_active) {
429 for (int i = 0; i < config->output_configs->length; i++) { 453 for (int i = 0; i < config->output_configs->length; i++) {
430 apply_output_config_to_outputs(config->output_configs->items[i]); 454 apply_output_config_to_outputs(config->output_configs->items[i]);
431 } 455 }
432 config->reloading = false; 456 config->reloading = false;
457 if (config->swaynag_config_errors.pid > 0) {
458 swaynag_show(&config->swaynag_config_errors);
459 }
433 } 460 }
434 461
435 if (old_config) { 462 if (old_config) {
@@ -441,7 +468,7 @@ bool load_main_config(const char *file, bool is_active) {
441} 468}
442 469
443static bool load_include_config(const char *path, const char *parent_dir, 470static bool load_include_config(const char *path, const char *parent_dir,
444 struct sway_config *config) { 471 struct sway_config *config, struct swaynag_instance *swaynag) {
445 // save parent config 472 // save parent config
446 const char *parent_config = config->current_config_path; 473 const char *parent_config = config->current_config_path;
447 474
@@ -485,7 +512,7 @@ static bool load_include_config(const char *path, const char *parent_dir,
485 list_add(config->config_chain, real_path); 512 list_add(config->config_chain, real_path);
486 int index = config->config_chain->length - 1; 513 int index = config->config_chain->length - 1;
487 514
488 if (!load_config(real_path, config)) { 515 if (!load_config(real_path, config, swaynag)) {
489 free(real_path); 516 free(real_path);
490 config->current_config_path = parent_config; 517 config->current_config_path = parent_config;
491 list_del(config->config_chain, index); 518 list_del(config->config_chain, index);
@@ -497,7 +524,8 @@ static bool load_include_config(const char *path, const char *parent_dir,
497 return true; 524 return true;
498} 525}
499 526
500bool load_include_configs(const char *path, struct sway_config *config) { 527bool load_include_configs(const char *path, struct sway_config *config,
528 struct swaynag_instance *swaynag) {
501 char *wd = getcwd(NULL, 0); 529 char *wd = getcwd(NULL, 0);
502 char *parent_path = strdup(config->current_config_path); 530 char *parent_path = strdup(config->current_config_path);
503 const char *parent_dir = dirname(parent_path); 531 const char *parent_dir = dirname(parent_path);
@@ -519,7 +547,7 @@ bool load_include_configs(const char *path, struct sway_config *config) {
519 char **w = p.we_wordv; 547 char **w = p.we_wordv;
520 size_t i; 548 size_t i;
521 for (i = 0; i < p.we_wordc; ++i) { 549 for (i = 0; i < p.we_wordc; ++i) {
522 load_include_config(w[i], parent_dir, config); 550 load_include_config(w[i], parent_dir, config, swaynag);
523 } 551 }
524 free(parent_path); 552 free(parent_path);
525 wordfree(&p); 553 wordfree(&p);
@@ -575,7 +603,8 @@ static char *expand_line(const char *block, const char *line, bool add_brace) {
575 return expanded; 603 return expanded;
576} 604}
577 605
578bool read_config(FILE *file, struct sway_config *config) { 606bool read_config(FILE *file, struct sway_config *config,
607 struct swaynag_instance *swaynag) {
579 bool reading_main_config = false; 608 bool reading_main_config = false;
580 char *this_config = NULL; 609 char *this_config = NULL;
581 size_t config_size = 0; 610 size_t config_size = 0;
@@ -665,6 +694,11 @@ bool read_config(FILE *file, struct sway_config *config) {
665 case CMD_INVALID: 694 case CMD_INVALID:
666 wlr_log(WLR_ERROR, "Error on line %i '%s': %s (%s)", line_number, 695 wlr_log(WLR_ERROR, "Error on line %i '%s': %s (%s)", line_number,
667 line, res->error, config->current_config_path); 696 line, res->error, config->current_config_path);
697 if (!config->validating) {
698 swaynag_log(config->swaynag_command, swaynag,
699 "Error on line %i (%s) '%s': %s", line_number,
700 config->current_config_path, line, res->error);
701 }
668 success = false; 702 success = false;
669 break; 703 break;
670 704
diff --git a/sway/main.c b/sway/main.c
index 477ffa5a..c02caf42 100644
--- a/sway/main.c
+++ b/sway/main.c
@@ -22,6 +22,7 @@
22#include "sway/debug.h" 22#include "sway/debug.h"
23#include "sway/desktop/transaction.h" 23#include "sway/desktop/transaction.h"
24#include "sway/server.h" 24#include "sway/server.h"
25#include "sway/swaynag.h"
25#include "sway/tree/layout.h" 26#include "sway/tree/layout.h"
26#include "sway/ipc-server.h" 27#include "sway/ipc-server.h"
27#include "ipc-client.h" 28#include "ipc-client.h"
@@ -416,11 +417,12 @@ int main(int argc, char **argv) {
416 log_env(); 417 log_env();
417 418
418 if (validate) { 419 if (validate) {
419 bool valid = load_main_config(config_path, false); 420 bool valid = load_main_config(config_path, false, true);
420 return valid ? 0 : 1; 421 return valid ? 0 : 1;
421 } 422 }
422 423
423 if (!load_main_config(config_path, false)) { 424 setenv("WAYLAND_DISPLAY", server.socket, true);
425 if (!load_main_config(config_path, false, false)) {
424 sway_terminate(EXIT_FAILURE); 426 sway_terminate(EXIT_FAILURE);
425 } 427 }
426 428
@@ -430,7 +432,6 @@ int main(int argc, char **argv) {
430 432
431 security_sanity_check(); 433 security_sanity_check();
432 434
433 setenv("WAYLAND_DISPLAY", server.socket, true);
434 if (!terminate_request) { 435 if (!terminate_request) {
435 if (!server_start_backend(&server)) { 436 if (!server_start_backend(&server)) {
436 sway_terminate(EXIT_FAILURE); 437 sway_terminate(EXIT_FAILURE);
@@ -452,6 +453,10 @@ int main(int argc, char **argv) {
452 } 453 }
453 transaction_commit_dirty(); 454 transaction_commit_dirty();
454 455
456 if (config->swaynag_config_errors.pid > 0) {
457 swaynag_show(&config->swaynag_config_errors);
458 }
459
455 if (!terminate_request) { 460 if (!terminate_request) {
456 server_run(&server); 461 server_run(&server);
457 } 462 }
diff --git a/sway/meson.build b/sway/meson.build
index a9503c3b..17406f6b 100644
--- a/sway/meson.build
+++ b/sway/meson.build
@@ -9,6 +9,7 @@ sway_sources = files(
9 'ipc-server.c', 9 'ipc-server.c',
10 'scratchpad.c', 10 'scratchpad.c',
11 'security.c', 11 'security.c',
12 'swaynag.c',
12 13
13 'desktop/desktop.c', 14 'desktop/desktop.c',
14 'desktop/idle_inhibit_v1.c', 15 'desktop/idle_inhibit_v1.c',
@@ -78,6 +79,7 @@ sway_sources = files(
78 'commands/split.c', 79 'commands/split.c',
79 'commands/sticky.c', 80 'commands/sticky.c',
80 'commands/swaybg_command.c', 81 'commands/swaybg_command.c',
82 'commands/swaynag_command.c',
81 'commands/swap.c', 83 'commands/swap.c',
82 'commands/title_format.c', 84 'commands/title_format.c',
83 'commands/unmark.c', 85 'commands/unmark.c',
diff --git a/sway/sway.5.scd b/sway/sway.5.scd
index d369d7b6..82df38e3 100644
--- a/sway/sway.5.scd
+++ b/sway/sway.5.scd
@@ -59,6 +59,13 @@ The following commands may only be used in the configuration file.
59 Executes custom background _command_. Default is _swaybg_. Refer to 59 Executes custom background _command_. Default is _swaybg_. Refer to
60 *output* below for more information. 60 *output* below for more information.
61 61
62*swaynag\_command* <command>
63 Executes custom command for _swaynag_. Default is _swaynag_. Additional
64 arguments may be appended to the end. This should only be used to either
65 direct sway to call swaynag from a custom path or to provide additional
66 arguments. This should be placed at the top of the config for the best
67 results.
68
62The following commands cannot be used directly in the configuration file. 69The following commands cannot be used directly in the configuration file.
63They are expected to be used with *bindsym* or at runtime through *swaymsg*(1). 70They are expected to be used with *bindsym* or at runtime through *swaymsg*(1).
64 71
diff --git a/sway/swaynag.c b/sway/swaynag.c
new file mode 100644
index 00000000..f5370807
--- /dev/null
+++ b/sway/swaynag.c
@@ -0,0 +1,94 @@
1#include <fcntl.h>
2#include <signal.h>
3#include <stdbool.h>
4#include <stdlib.h>
5#include <stdio.h>
6#include <sys/types.h>
7#include <unistd.h>
8#include "log.h"
9#include "sway/swaynag.h"
10
11bool swaynag_spawn(const char *swaynag_command,
12 struct swaynag_instance *swaynag) {
13 if (swaynag->detailed) {
14 if (pipe(swaynag->fd) != 0) {
15 wlr_log(WLR_ERROR, "Failed to create pipe for swaynag");
16 return false;
17 }
18 fcntl(swaynag->fd[1], F_SETFD, FD_CLOEXEC);
19 }
20
21 pid_t pid;
22 if ((pid = fork()) == 0) {
23 if (swaynag->detailed) {
24 close(swaynag->fd[1]);
25 dup2(swaynag->fd[0], STDIN_FILENO);
26 close(swaynag->fd[0]);
27 }
28
29 size_t length = strlen(swaynag_command) + strlen(swaynag->args) + 2;
30 char *cmd = malloc(length);
31 snprintf(cmd, length, "%s %s", swaynag_command, swaynag->args);
32 execl("/bin/sh", "/bin/sh", "-c", cmd, NULL);
33 _exit(0);
34 } else if (pid < 0) {
35 wlr_log(WLR_ERROR, "Failed to create fork for swaynag");
36 if (swaynag->detailed) {
37 close(swaynag->fd[0]);
38 close(swaynag->fd[1]);
39 }
40 return false;
41 }
42
43 if (swaynag->detailed) {
44 close(swaynag->fd[0]);
45 }
46 swaynag->pid = pid;
47 return true;
48}
49
50
51void swaynag_kill(struct swaynag_instance *swaynag) {
52 if (swaynag->pid > 0) {
53 kill(swaynag->pid, SIGTERM);
54 swaynag->pid = -1;
55 }
56}
57
58void swaynag_log(const char *swaynag_command, struct swaynag_instance *swaynag,
59 const char *fmt, ...) {
60 if (!swaynag->detailed) {
61 wlr_log(WLR_ERROR, "Attempting to write to non-detailed swaynag inst");
62 return;
63 }
64
65 if (swaynag->pid <= 0 && !swaynag_spawn(swaynag_command, swaynag)) {
66 return;
67 }
68
69 va_list args;
70 va_start(args, fmt);
71 size_t length = vsnprintf(NULL, 0, fmt, args) + 1;
72 va_end(args);
73
74 char *temp = malloc(length + 1);
75 if (!temp) {
76 wlr_log(WLR_ERROR, "Failed to allocate buffer for swaynag log entry.");
77 return;
78 }
79
80 va_start(args, fmt);
81 vsnprintf(temp, length, fmt, args);
82 va_end(args);
83
84 write(swaynag->fd[1], temp, length);
85
86 free(temp);
87}
88
89void swaynag_show(struct swaynag_instance *swaynag) {
90 if (swaynag->detailed && swaynag->pid > 0) {
91 close(swaynag->fd[1]);
92 }
93}
94