summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Taiyu <taiyu.len@gmail.com>2015-08-12 21:06:09 -0700
committerLibravatar Taiyu <taiyu.len@gmail.com>2015-08-12 21:06:09 -0700
commit65406cb61baed6ac24bcb6c307ed5a95922b2fc1 (patch)
tree3bfcbf008783d81e478c2d1ffacb0b881b1eb406
parentmoving stuff around (diff)
downloadsway-65406cb61baed6ac24bcb6c307ed5a95922b2fc1.tar.gz
sway-65406cb61baed6ac24bcb6c307ed5a95922b2fc1.tar.zst
sway-65406cb61baed6ac24bcb6c307ed5a95922b2fc1.zip
safer forking, reduce duplicate code, cleanup zombie processes
-rw-r--r--sway/commands.c74
1 files changed, 44 insertions, 30 deletions
diff --git a/sway/commands.c b/sway/commands.c
index 870a2377..f4de72d8 100644
--- a/sway/commands.c
+++ b/sway/commands.c
@@ -5,6 +5,7 @@
5#include <stdlib.h> 5#include <stdlib.h>
6#include <string.h> 6#include <string.h>
7#include <unistd.h> 7#include <unistd.h>
8#include <sys/wait.h>
8#include <ctype.h> 9#include <ctype.h>
9#include "stringop.h" 10#include "stringop.h"
10#include "layout.h" 11#include "layout.h"
@@ -29,6 +30,8 @@ struct modifier_key modifiers[] = {
29 { "Mod5", WLC_BIT_MOD_MOD5 }, 30 { "Mod5", WLC_BIT_MOD_MOD5 },
30}; 31};
31 32
33
34
32bool cmd_bindsym(struct sway_config *config, int argc, char **argv) { 35bool cmd_bindsym(struct sway_config *config, int argc, char **argv) {
33 if (argc < 2) { 36 if (argc < 2) {
34 sway_log(L_ERROR, "Invalid set command (expected 2 arguments, got %d)", argc); 37 sway_log(L_ERROR, "Invalid set command (expected 2 arguments, got %d)", argc);
@@ -73,44 +76,55 @@ bool cmd_bindsym(struct sway_config *config, int argc, char **argv) {
73 return true; 76 return true;
74} 77}
75 78
76bool cmd_exec(struct sway_config *config, int argc, char **argv) { 79static void cmd_exec_cleanup(int signal) {
80 while (waitpid((pid_t)-1, 0, WNOHANG) > 0){};
81}
82
83static bool cmd_exec_always(struct sway_config *config, int argc, char **argv) {
84 /* setup signal handler to cleanup dead proccesses */
85 /* TODO: replace this with a function that has constructor attribute? */
86 static bool cleanup = false;
87 if(cleanup == false) {
88 signal(SIGCHLD, cmd_exec_cleanup);
89 cleanup = true;
90 }
91
77 if (argc < 1) { 92 if (argc < 1) {
78 sway_log(L_ERROR, "Invalid exec command (expected at least 1 argument, got %d)", argc); 93 sway_log(L_ERROR, "Invalid exec command (expected at least 1 argument, got %d)", argc);
79 return false; 94 return false;
80 } 95 }
81 96
82 if (config->reloading) { 97 pid_t pid = fork();
83 sway_log(L_DEBUG, "Ignoring exec %s due to reload", join_args(argv, argc)); 98 /* Failed to fork */
84 return true; 99 if (pid < 0) {
100 sway_log(L_ERROR, "exec command failed, sway did not fork");
101 return false;
85 } 102 }
86 103 /* Child process */
87 if (fork() == 0) { 104 if (pid == 0) {
88 char *args = join_args(argv, argc); 105 char *args = join_args(argv, argc);
89 sway_log(L_DEBUG, "Executing %s", args); 106 sway_log(L_DEBUG, "Executing %s", args);
90 execl("/bin/sh", "sh", "-c", args, (char *)NULL); 107 execl("/bin/sh", "sh", "-c", args, (char *)NULL);
108 /* Execl doesnt return unless failure */
109 sway_log(L_ERROR, "could not find /bin/sh");
91 free(args); 110 free(args);
92 exit(0); 111 exit(-1);
93 } 112 }
113 /* Parent */
94 return true; 114 return true;
95} 115}
96 116
97bool cmd_exec_always(struct sway_config *config, int argc, char **argv) { 117static bool cmd_exec(struct sway_config *config, int argc, char **argv) {
98 if (argc < 1) { 118 if (config->reloading) {
99 sway_log(L_ERROR, "Invalid exec_always command (expected at least 1 argument, got %d)", argc);
100 return false;
101 }
102
103 if (fork() == 0) {
104 char *args = join_args(argv, argc); 119 char *args = join_args(argv, argc);
105 sway_log(L_DEBUG, "Executing %s", args); 120 sway_log(L_DEBUG, "Ignoring exec %s due to reload", args);
106 execl("/bin/sh", "sh", "-c", args, (char *)NULL);
107 free(args); 121 free(args);
108 exit(0); 122 return true;
109 } 123 }
110 return true; 124 return cmd_exec_always(config, argc, argv);
111} 125}
112 126
113bool cmd_exit(struct sway_config *config, int argc, char **argv) { 127static bool cmd_exit(struct sway_config *config, int argc, char **argv) {
114 if (argc != 0) { 128 if (argc != 0) {
115 sway_log(L_ERROR, "Invalid exit command (expected 1 arguments, got %d)", argc); 129 sway_log(L_ERROR, "Invalid exit command (expected 1 arguments, got %d)", argc);
116 return false; 130 return false;
@@ -120,7 +134,7 @@ bool cmd_exit(struct sway_config *config, int argc, char **argv) {
120 return true; 134 return true;
121} 135}
122 136
123bool cmd_focus(struct sway_config *config, int argc, char **argv) { 137static bool cmd_focus(struct sway_config *config, int argc, char **argv) {
124 if (argc != 1) { 138 if (argc != 1) {
125 sway_log(L_ERROR, "Invalid focus command (expected 1 arguments, got %d)", argc); 139 sway_log(L_ERROR, "Invalid focus command (expected 1 arguments, got %d)", argc);
126 return false; 140 return false;
@@ -139,7 +153,7 @@ bool cmd_focus(struct sway_config *config, int argc, char **argv) {
139 return true; 153 return true;
140} 154}
141 155
142bool cmd_focus_follows_mouse(struct sway_config *config, int argc, char **argv) { 156static bool cmd_focus_follows_mouse(struct sway_config *config, int argc, char **argv) {
143 if (argc != 1) { 157 if (argc != 1) {
144 sway_log(L_ERROR, "Invalid focus_follows_mouse command (expected 1 arguments, got %d)", argc); 158 sway_log(L_ERROR, "Invalid focus_follows_mouse command (expected 1 arguments, got %d)", argc);
145 return false; 159 return false;
@@ -149,7 +163,7 @@ bool cmd_focus_follows_mouse(struct sway_config *config, int argc, char **argv)
149 return true; 163 return true;
150} 164}
151 165
152bool cmd_layout(struct sway_config *config, int argc, char **argv) { 166static bool cmd_layout(struct sway_config *config, int argc, char **argv) {
153 if (argc < 1) { 167 if (argc < 1) {
154 sway_log(L_ERROR, "Invalid layout command (expected at least 1 argument, got %d)", argc); 168 sway_log(L_ERROR, "Invalid layout command (expected at least 1 argument, got %d)", argc);
155 return false; 169 return false;
@@ -174,7 +188,7 @@ bool cmd_layout(struct sway_config *config, int argc, char **argv) {
174 return true; 188 return true;
175} 189}
176 190
177bool cmd_reload(struct sway_config *config, int argc, char **argv) { 191static bool cmd_reload(struct sway_config *config, int argc, char **argv) {
178 if (argc != 0) { 192 if (argc != 0) {
179 sway_log(L_ERROR, "Invalid reload command (expected 0 arguments, got %d)", argc); 193 sway_log(L_ERROR, "Invalid reload command (expected 0 arguments, got %d)", argc);
180 return false; 194 return false;
@@ -186,7 +200,7 @@ bool cmd_reload(struct sway_config *config, int argc, char **argv) {
186 return true; 200 return true;
187} 201}
188 202
189bool cmd_set(struct sway_config *config, int argc, char **argv) { 203static bool cmd_set(struct sway_config *config, int argc, char **argv) {
190 if (argc != 2) { 204 if (argc != 2) {
191 sway_log(L_ERROR, "Invalid set command (expected 2 arguments, got %d)", argc); 205 sway_log(L_ERROR, "Invalid set command (expected 2 arguments, got %d)", argc);
192 return false; 206 return false;
@@ -200,7 +214,7 @@ bool cmd_set(struct sway_config *config, int argc, char **argv) {
200 return true; 214 return true;
201} 215}
202 216
203bool _do_split(struct sway_config *config, int argc, char **argv, int layout) { 217static bool _do_split(struct sway_config *config, int argc, char **argv, int layout) {
204 if (argc != 0) { 218 if (argc != 0) {
205 sway_log(L_ERROR, "Invalid splitv command (expected 0 arguments, got %d)", argc); 219 sway_log(L_ERROR, "Invalid splitv command (expected 0 arguments, got %d)", argc);
206 return false; 220 return false;
@@ -225,15 +239,15 @@ bool _do_split(struct sway_config *config, int argc, char **argv, int layout) {
225 return true; 239 return true;
226} 240}
227 241
228bool cmd_splitv(struct sway_config *config, int argc, char **argv) { 242static bool cmd_splitv(struct sway_config *config, int argc, char **argv) {
229 return _do_split(config, argc, argv, L_VERT); 243 return _do_split(config, argc, argv, L_VERT);
230} 244}
231 245
232bool cmd_splith(struct sway_config *config, int argc, char **argv) { 246static bool cmd_splith(struct sway_config *config, int argc, char **argv) {
233 return _do_split(config, argc, argv, L_HORIZ); 247 return _do_split(config, argc, argv, L_HORIZ);
234} 248}
235 249
236bool cmd_log_colors(struct sway_config *config, int argc, char **argv) { 250static bool cmd_log_colors(struct sway_config *config, int argc, char **argv) {
237 if (argc != 1) { 251 if (argc != 1) {
238 sway_log(L_ERROR, "Invalid log_colors command (expected 1 argument, got %d)", argc); 252 sway_log(L_ERROR, "Invalid log_colors command (expected 1 argument, got %d)", argc);
239 return false; 253 return false;
@@ -248,7 +262,7 @@ bool cmd_log_colors(struct sway_config *config, int argc, char **argv) {
248 return true; 262 return true;
249} 263}
250 264
251bool cmd_fullscreen(struct sway_config *config, int argc, char **argv) { 265static bool cmd_fullscreen(struct sway_config *config, int argc, char **argv) {
252 if (argc != 1) { 266 if (argc != 1) {
253 sway_log(L_ERROR, "Invalid fullscreen command (expected 1 arguments, got %d)", argc); 267 sway_log(L_ERROR, "Invalid fullscreen command (expected 1 arguments, got %d)", argc);
254 return false; 268 return false;
@@ -262,7 +276,7 @@ bool cmd_fullscreen(struct sway_config *config, int argc, char **argv) {
262 return true; 276 return true;
263} 277}
264 278
265bool cmd_workspace(struct sway_config *config, int argc, char **argv) { 279static bool cmd_workspace(struct sway_config *config, int argc, char **argv) {
266 if (argc != 1) { 280 if (argc != 1) {
267 sway_log(L_ERROR, "Invalid workspace command (expected 1 arguments, got %d)", argc); 281 sway_log(L_ERROR, "Invalid workspace command (expected 1 arguments, got %d)", argc);
268 return false; 282 return false;