diff options
author | Brian Ashworth <bosrsf04@gmail.com> | 2018-08-02 21:37:29 -0400 |
---|---|---|
committer | Brian Ashworth <bosrsf04@gmail.com> | 2018-08-03 10:37:35 -0400 |
commit | a7f7d4a488c8d3b2461122765f9904c8a411a583 (patch) | |
tree | 7abee51265a8b9550c62255d0c6649935ee1d6a2 /sway/swaynag.c | |
parent | Show swaynag on config errors (diff) | |
download | sway-a7f7d4a488c8d3b2461122765f9904c8a411a583.tar.gz sway-a7f7d4a488c8d3b2461122765f9904c8a411a583.tar.zst sway-a7f7d4a488c8d3b2461122765f9904c8a411a583.zip |
Write to swaynag pipe fd directly on config errors
Diffstat (limited to 'sway/swaynag.c')
-rw-r--r-- | sway/swaynag.c | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/sway/swaynag.c b/sway/swaynag.c new file mode 100644 index 00000000..2dc0cb21 --- /dev/null +++ b/sway/swaynag.c | |||
@@ -0,0 +1,103 @@ | |||
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 | |||
11 | void swaynag_clone(struct swaynag_instance *dest, | ||
12 | struct swaynag_instance *src) { | ||
13 | dest->args = src->args; | ||
14 | dest->pid = src->pid; | ||
15 | dest->fd[0] = src->fd[0]; | ||
16 | dest->fd[1] = src->fd[1]; | ||
17 | dest->detailed = src->detailed; | ||
18 | } | ||
19 | |||
20 | bool swaynag_spawn(const char *swaynag_command, | ||
21 | struct swaynag_instance *swaynag) { | ||
22 | if (swaynag->detailed) { | ||
23 | if (pipe(swaynag->fd) != 0) { | ||
24 | wlr_log(WLR_ERROR, "Failed to create pipe for swaynag"); | ||
25 | return false; | ||
26 | } | ||
27 | fcntl(swaynag->fd[1], F_SETFD, FD_CLOEXEC); | ||
28 | } | ||
29 | |||
30 | pid_t pid; | ||
31 | if ((pid = fork()) == 0) { | ||
32 | if (swaynag->detailed) { | ||
33 | close(swaynag->fd[1]); | ||
34 | dup2(swaynag->fd[0], STDIN_FILENO); | ||
35 | close(swaynag->fd[0]); | ||
36 | } | ||
37 | |||
38 | size_t length = strlen(swaynag_command) + strlen(swaynag->args) + 2; | ||
39 | char *cmd = malloc(length); | ||
40 | snprintf(cmd, length, "%s %s", swaynag_command, swaynag->args); | ||
41 | execl("/bin/sh", "/bin/sh", "-c", cmd, NULL); | ||
42 | _exit(0); | ||
43 | } else if (pid < 0) { | ||
44 | wlr_log(WLR_ERROR, "Failed to create fork for swaynag"); | ||
45 | if (swaynag->detailed) { | ||
46 | close(swaynag->fd[0]); | ||
47 | close(swaynag->fd[1]); | ||
48 | } | ||
49 | return false; | ||
50 | } | ||
51 | |||
52 | if (swaynag->detailed) { | ||
53 | close(swaynag->fd[0]); | ||
54 | } | ||
55 | swaynag->pid = pid; | ||
56 | return true; | ||
57 | } | ||
58 | |||
59 | |||
60 | void swaynag_kill(struct swaynag_instance *swaynag) { | ||
61 | if (swaynag->pid > 0) { | ||
62 | kill(swaynag->pid, SIGTERM); | ||
63 | swaynag->pid = -1; | ||
64 | } | ||
65 | } | ||
66 | |||
67 | void swaynag_log(const char *swaynag_command, struct swaynag_instance *swaynag, | ||
68 | const char *fmt, ...) { | ||
69 | if (!swaynag->detailed) { | ||
70 | wlr_log(WLR_ERROR, "Attempting to write to non-detailed swaynag inst"); | ||
71 | return; | ||
72 | } | ||
73 | |||
74 | if (swaynag->pid <= 0 && !swaynag_spawn(swaynag_command, swaynag)) { | ||
75 | return; | ||
76 | } | ||
77 | |||
78 | va_list args; | ||
79 | va_start(args, fmt); | ||
80 | size_t length = vsnprintf(NULL, 0, fmt, args) + 1; | ||
81 | va_end(args); | ||
82 | |||
83 | char *temp = malloc(length + 1); | ||
84 | if (!temp) { | ||
85 | wlr_log(WLR_ERROR, "Failed to allocate buffer for swaynag log entry."); | ||
86 | return; | ||
87 | } | ||
88 | |||
89 | va_start(args, fmt); | ||
90 | vsnprintf(temp, length, fmt, args); | ||
91 | va_end(args); | ||
92 | |||
93 | write(swaynag->fd[1], temp, length); | ||
94 | |||
95 | free(temp); | ||
96 | } | ||
97 | |||
98 | void swaynag_show(struct swaynag_instance *swaynag) { | ||
99 | if (swaynag->detailed && swaynag->pid > 0) { | ||
100 | close(swaynag->fd[1]); | ||
101 | } | ||
102 | } | ||
103 | |||