diff options
Diffstat (limited to 'sway/main.c')
-rw-r--r-- | sway/main.c | 254 |
1 files changed, 93 insertions, 161 deletions
diff --git a/sway/main.c b/sway/main.c index cc9147b8..efb674b6 100644 --- a/sway/main.c +++ b/sway/main.c | |||
@@ -1,58 +1,46 @@ | |||
1 | #define _XOPEN_SOURCE 700 | 1 | #define _XOPEN_SOURCE 700 |
2 | #define _POSIX_C_SOURCE 200112L | 2 | #define _POSIX_C_SOURCE 200112L |
3 | #include <stdio.h> | 3 | #include <getopt.h> |
4 | #include <stdlib.h> | 4 | #include <signal.h> |
5 | #include <stdbool.h> | 5 | #include <stdbool.h> |
6 | #include <wlc/wlc.h> | 6 | #include <stdlib.h> |
7 | #include <sys/wait.h> | 7 | #include <stdio.h> |
8 | #include <sys/types.h> | 8 | #include <string.h> |
9 | #include <sys/stat.h> | 9 | #include <sys/stat.h> |
10 | #include <sys/types.h> | ||
11 | #include <sys/wait.h> | ||
10 | #include <sys/un.h> | 12 | #include <sys/un.h> |
11 | #include <signal.h> | ||
12 | #include <unistd.h> | 13 | #include <unistd.h> |
13 | #include <getopt.h> | ||
14 | #ifdef __linux__ | 14 | #ifdef __linux__ |
15 | #include <sys/capability.h> | 15 | #include <sys/capability.h> |
16 | #include <sys/prctl.h> | 16 | #include <sys/prctl.h> |
17 | #endif | 17 | #endif |
18 | #include "sway/extensions.h" | 18 | #include <wlr/util/log.h> |
19 | #include "sway/layout.h" | ||
20 | #include "sway/config.h" | 19 | #include "sway/config.h" |
21 | #include "sway/security.h" | 20 | #include "sway/debug.h" |
22 | #include "sway/handlers.h" | 21 | #include "sway/server.h" |
23 | #include "sway/input.h" | 22 | #include "sway/tree/layout.h" |
24 | #include "sway/ipc-server.h" | 23 | #include "sway/ipc-server.h" |
25 | #include "ipc-client.h" | 24 | #include "ipc-client.h" |
26 | #include "readline.h" | 25 | #include "readline.h" |
27 | #include "stringop.h" | 26 | #include "stringop.h" |
28 | #include "sway.h" | ||
29 | #include "log.h" | ||
30 | #include "util.h" | 27 | #include "util.h" |
31 | 28 | ||
32 | static bool terminate_request = false; | 29 | static bool terminate_request = false; |
33 | static int exit_value = 0; | 30 | static int exit_value = 0; |
31 | struct sway_server server; | ||
34 | 32 | ||
35 | void sway_terminate(int exit_code) { | 33 | void sway_terminate(int exit_code) { |
36 | terminate_request = true; | 34 | terminate_request = true; |
37 | exit_value = exit_code; | 35 | exit_value = exit_code; |
38 | wlc_terminate(); | 36 | wl_display_terminate(server.wl_display); |
39 | } | 37 | } |
40 | 38 | ||
41 | void sig_handler(int signal) { | 39 | void sig_handler(int signal) { |
42 | close_views(&root_container); | 40 | //close_views(&root_container); |
43 | sway_terminate(EXIT_SUCCESS); | 41 | sway_terminate(EXIT_SUCCESS); |
44 | } | 42 | } |
45 | 43 | ||
46 | static void wlc_log_handler(enum wlc_log_type type, const char *str) { | ||
47 | if (type == WLC_LOG_ERROR) { | ||
48 | sway_log(L_ERROR, "[wlc] %s", str); | ||
49 | } else if (type == WLC_LOG_WARN) { | ||
50 | sway_log(L_INFO, "[wlc] %s", str); | ||
51 | } else { | ||
52 | sway_log(L_DEBUG, "[wlc] %s", str); | ||
53 | } | ||
54 | } | ||
55 | |||
56 | void detect_raspi() { | 44 | void detect_raspi() { |
57 | bool raspi = false; | 45 | bool raspi = false; |
58 | FILE *f = fopen("/sys/firmware/devicetree/base/model", "r"); | 46 | FILE *f = fopen("/sys/firmware/devicetree/base/model", "r"); |
@@ -98,23 +86,16 @@ void detect_proprietary() { | |||
98 | if (!f) { | 86 | if (!f) { |
99 | return; | 87 | return; |
100 | } | 88 | } |
101 | bool nvidia = false, nvidia_modeset = false, nvidia_uvm = false, nvidia_drm = false; | ||
102 | while (!feof(f)) { | 89 | while (!feof(f)) { |
103 | char *line; | 90 | char *line; |
104 | if (!(line = read_line(f))) { | 91 | if (!(line = read_line(f))) { |
105 | break; | 92 | break; |
106 | } | 93 | } |
107 | if (strstr(line, "nvidia")) { | 94 | if (strstr(line, "nvidia")) { |
108 | nvidia = true; | 95 | fprintf(stderr, "\x1B[1;31mWarning: Proprietary Nvidia drivers are " |
109 | } | 96 | "NOT supported. Use Nouveau.\x1B[0m\n"); |
110 | if (strstr(line, "nvidia_modeset")) { | 97 | free(line); |
111 | nvidia_modeset = true; | 98 | break; |
112 | } | ||
113 | if (strstr(line, "nvidia_uvm")) { | ||
114 | nvidia_uvm = true; | ||
115 | } | ||
116 | if (strstr(line, "nvidia_drm")) { | ||
117 | nvidia_drm = true; | ||
118 | } | 99 | } |
119 | if (strstr(line, "fglrx")) { | 100 | if (strstr(line, "fglrx")) { |
120 | fprintf(stderr, "\x1B[1;31mWarning: Proprietary AMD drivers do " | 101 | fprintf(stderr, "\x1B[1;31mWarning: Proprietary AMD drivers do " |
@@ -125,52 +106,6 @@ void detect_proprietary() { | |||
125 | free(line); | 106 | free(line); |
126 | } | 107 | } |
127 | fclose(f); | 108 | fclose(f); |
128 | if (nvidia) { | ||
129 | fprintf(stderr, "\x1B[1;31mWarning: Proprietary nvidia driver support " | ||
130 | "is considered experimental. Nouveau is strongly recommended." | ||
131 | "\x1B[0m\n"); | ||
132 | if (!nvidia_modeset || !nvidia_uvm || !nvidia_drm) { | ||
133 | fprintf(stderr, "\x1B[1;31mWarning: You do not have all of the " | ||
134 | "necessary kernel modules loaded for nvidia support. " | ||
135 | "You need nvidia, nvidia_modeset, nvidia_uvm, and nvidia_drm." | ||
136 | "\x1B[0m\n"); | ||
137 | } | ||
138 | #ifdef __linux__ | ||
139 | f = fopen("/sys/module/nvidia_drm/parameters/modeset", "r"); | ||
140 | if (f) { | ||
141 | char *line = read_line(f); | ||
142 | if (line && strstr(line, "Y")) { | ||
143 | // nvidia-drm.modeset is set to 0 | ||
144 | fprintf(stderr, "\x1B[1;31mWarning: You must load " | ||
145 | "nvidia-drm with the modeset option on to use " | ||
146 | "the proprietary driver. Consider adding " | ||
147 | "nvidia-drm.modeset=1 to your kernel command line " | ||
148 | "parameters.\x1B[0m\n"); | ||
149 | } | ||
150 | fclose(f); | ||
151 | free(line); | ||
152 | } else { | ||
153 | // nvidia-drm.modeset is not set | ||
154 | fprintf(stderr, "\x1B[1;31mWarning: You must load " | ||
155 | "nvidia-drm with the modeset option on to use " | ||
156 | "the proprietary driver. Consider adding " | ||
157 | "nvidia-drm.modeset=1 to your kernel command line " | ||
158 | "parameters.\x1B[0m\n"); | ||
159 | } | ||
160 | #else | ||
161 | f = fopen("/proc/cmdline", "r"); | ||
162 | if (f) { | ||
163 | char *line = read_line(f); | ||
164 | if (line && !strstr(line, "nvidia-drm.modeset=1")) { | ||
165 | fprintf(stderr, "\x1B[1;31mWarning: You must add " | ||
166 | "nvidia-drm.modeset=1 to your kernel command line to use " | ||
167 | "the proprietary driver.\x1B[0m\n"); | ||
168 | } | ||
169 | fclose(f); | ||
170 | free(line); | ||
171 | } | ||
172 | #endif | ||
173 | } | ||
174 | } | 109 | } |
175 | 110 | ||
176 | void run_as_ipc_client(char *command, char *socket_path) { | 111 | void run_as_ipc_client(char *command, char *socket_path) { |
@@ -184,27 +119,15 @@ void run_as_ipc_client(char *command, char *socket_path) { | |||
184 | static void log_env() { | 119 | static void log_env() { |
185 | const char *log_vars[] = { | 120 | const char *log_vars[] = { |
186 | "PATH", | 121 | "PATH", |
187 | "LD_LOAD_PATH", | 122 | "LD_LIBRARY_PATH", |
188 | "LD_PRELOAD_PATH", | 123 | "LD_PRELOAD_PATH", |
189 | "LD_LIBRARY_PATH", | 124 | "LD_LIBRARY_PATH", |
190 | "SWAY_CURSOR_THEME", | 125 | "SWAY_CURSOR_THEME", |
191 | "SWAY_CURSOR_SIZE", | 126 | "SWAY_CURSOR_SIZE", |
192 | "SWAYSOCK", | 127 | "SWAYSOCK" |
193 | "WLC_DRM_DEVICE", | ||
194 | "WLC_SHM", | ||
195 | "WLC_OUTPUTS", | ||
196 | "WLC_XWAYLAND", | ||
197 | "WLC_LIBINPUT", | ||
198 | "WLC_REPEAT_DELAY", | ||
199 | "WLC_REPEAT_RATE", | ||
200 | "XKB_DEFAULT_RULES", | ||
201 | "XKB_DEFAULT_MODEL", | ||
202 | "XKB_DEFAULT_LAYOUT", | ||
203 | "XKB_DEFAULT_VARIANT", | ||
204 | "XKB_DEFAULT_OPTIONS", | ||
205 | }; | 128 | }; |
206 | for (size_t i = 0; i < sizeof(log_vars) / sizeof(char *); ++i) { | 129 | for (size_t i = 0; i < sizeof(log_vars) / sizeof(char *); ++i) { |
207 | sway_log(L_INFO, "%s=%s", log_vars[i], getenv(log_vars[i])); | 130 | wlr_log(L_INFO, "%s=%s", log_vars[i], getenv(log_vars[i])); |
208 | } | 131 | } |
209 | } | 132 | } |
210 | 133 | ||
@@ -219,14 +142,14 @@ static void log_distro() { | |||
219 | for (size_t i = 0; i < sizeof(paths) / sizeof(char *); ++i) { | 142 | for (size_t i = 0; i < sizeof(paths) / sizeof(char *); ++i) { |
220 | FILE *f = fopen(paths[i], "r"); | 143 | FILE *f = fopen(paths[i], "r"); |
221 | if (f) { | 144 | if (f) { |
222 | sway_log(L_INFO, "Contents of %s:", paths[i]); | 145 | wlr_log(L_INFO, "Contents of %s:", paths[i]); |
223 | while (!feof(f)) { | 146 | while (!feof(f)) { |
224 | char *line; | 147 | char *line; |
225 | if (!(line = read_line(f))) { | 148 | if (!(line = read_line(f))) { |
226 | break; | 149 | break; |
227 | } | 150 | } |
228 | if (*line) { | 151 | if (*line) { |
229 | sway_log(L_INFO, "%s", line); | 152 | wlr_log(L_INFO, "%s", line); |
230 | } | 153 | } |
231 | free(line); | 154 | free(line); |
232 | } | 155 | } |
@@ -236,9 +159,10 @@ static void log_distro() { | |||
236 | } | 159 | } |
237 | 160 | ||
238 | static void log_kernel() { | 161 | static void log_kernel() { |
162 | return; | ||
239 | FILE *f = popen("uname -a", "r"); | 163 | FILE *f = popen("uname -a", "r"); |
240 | if (!f) { | 164 | if (!f) { |
241 | sway_log(L_INFO, "Unable to determine kernel version"); | 165 | wlr_log(L_INFO, "Unable to determine kernel version"); |
242 | return; | 166 | return; |
243 | } | 167 | } |
244 | while (!feof(f)) { | 168 | while (!feof(f)) { |
@@ -247,7 +171,7 @@ static void log_kernel() { | |||
247 | break; | 171 | break; |
248 | } | 172 | } |
249 | if (*line) { | 173 | if (*line) { |
250 | sway_log(L_INFO, "%s", line); | 174 | wlr_log(L_INFO, "%s", line); |
251 | } | 175 | } |
252 | free(line); | 176 | free(line); |
253 | } | 177 | } |
@@ -258,14 +182,14 @@ static void security_sanity_check() { | |||
258 | // TODO: Notify users visually if this has issues | 182 | // TODO: Notify users visually if this has issues |
259 | struct stat s; | 183 | struct stat s; |
260 | if (stat("/proc", &s)) { | 184 | if (stat("/proc", &s)) { |
261 | sway_log(L_ERROR, | 185 | wlr_log(L_ERROR, |
262 | "!! DANGER !! /proc is not available - sway CANNOT enforce security rules!"); | 186 | "!! DANGER !! /proc is not available - sway CANNOT enforce security rules!"); |
263 | } | 187 | } |
264 | #ifdef __linux__ | 188 | #ifdef __linux__ |
265 | cap_flag_value_t v; | 189 | cap_flag_value_t v; |
266 | cap_t cap = cap_get_proc(); | 190 | cap_t cap = cap_get_proc(); |
267 | if (!cap || cap_get_flag(cap, CAP_SYS_PTRACE, CAP_PERMITTED, &v) != 0 || v != CAP_SET) { | 191 | if (!cap || cap_get_flag(cap, CAP_SYS_PTRACE, CAP_PERMITTED, &v) != 0 || v != CAP_SET) { |
268 | sway_log(L_ERROR, | 192 | wlr_log(L_ERROR, |
269 | "!! DANGER !! Sway does not have CAP_SYS_PTRACE and cannot enforce security rules for processes running as other users."); | 193 | "!! DANGER !! Sway does not have CAP_SYS_PTRACE and cannot enforce security rules for processes running as other users."); |
270 | } | 194 | } |
271 | if (cap) { | 195 | if (cap) { |
@@ -281,13 +205,13 @@ static void executable_sanity_check() { | |||
281 | stat(exe, &sb); | 205 | stat(exe, &sb); |
282 | // We assume that cap_get_file returning NULL implies ENODATA | 206 | // We assume that cap_get_file returning NULL implies ENODATA |
283 | if (sb.st_mode & (S_ISUID|S_ISGID) && cap_get_file(exe)) { | 207 | if (sb.st_mode & (S_ISUID|S_ISGID) && cap_get_file(exe)) { |
284 | sway_log(L_ERROR, | 208 | wlr_log(L_ERROR, |
285 | "sway executable has both the s(g)uid bit AND file caps set."); | 209 | "sway executable has both the s(g)uid bit AND file caps set."); |
286 | sway_log(L_ERROR, | 210 | wlr_log(L_ERROR, |
287 | "This is strongly discouraged (and completely broken)."); | 211 | "This is strongly discouraged (and completely broken)."); |
288 | sway_log(L_ERROR, | 212 | wlr_log(L_ERROR, |
289 | "Please clear one of them (either the suid bit, or the file caps)."); | 213 | "Please clear one of them (either the suid bit, or the file caps)."); |
290 | sway_log(L_ERROR, | 214 | wlr_log(L_ERROR, |
291 | "If unsure, strip the file caps."); | 215 | "If unsure, strip the file caps."); |
292 | exit(EXIT_FAILURE); | 216 | exit(EXIT_FAILURE); |
293 | } | 217 | } |
@@ -295,6 +219,37 @@ static void executable_sanity_check() { | |||
295 | #endif | 219 | #endif |
296 | } | 220 | } |
297 | 221 | ||
222 | static void drop_permissions(bool keep_caps) { | ||
223 | if (getuid() != geteuid() || getgid() != getegid()) { | ||
224 | if (setgid(getgid()) != 0) { | ||
225 | wlr_log(L_ERROR, "Unable to drop root"); | ||
226 | exit(EXIT_FAILURE); | ||
227 | } | ||
228 | if (setuid(getuid()) != 0) { | ||
229 | wlr_log(L_ERROR, "Unable to drop root"); | ||
230 | exit(EXIT_FAILURE); | ||
231 | } | ||
232 | } | ||
233 | if (setuid(0) != -1) { | ||
234 | wlr_log(L_ERROR, "Root privileges can be restored."); | ||
235 | exit(EXIT_FAILURE); | ||
236 | } | ||
237 | #ifdef __linux__ | ||
238 | if (keep_caps) { | ||
239 | // Drop every cap except CAP_SYS_PTRACE | ||
240 | cap_t caps = cap_init(); | ||
241 | cap_value_t keep = CAP_SYS_PTRACE; | ||
242 | wlr_log(L_INFO, "Dropping extra capabilities"); | ||
243 | if (cap_set_flag(caps, CAP_PERMITTED, 1, &keep, CAP_SET) || | ||
244 | cap_set_flag(caps, CAP_EFFECTIVE, 1, &keep, CAP_SET) || | ||
245 | cap_set_proc(caps)) { | ||
246 | wlr_log(L_ERROR, "Failed to drop extra capabilities"); | ||
247 | exit(EXIT_FAILURE); | ||
248 | } | ||
249 | } | ||
250 | #endif | ||
251 | } | ||
252 | |||
298 | int main(int argc, char **argv) { | 253 | int main(int argc, char **argv) { |
299 | static int verbose = 0, debug = 0, validate = 0; | 254 | static int verbose = 0, debug = 0, validate = 0; |
300 | 255 | ||
@@ -334,7 +289,7 @@ int main(int argc, char **argv) { | |||
334 | int c; | 289 | int c; |
335 | while (1) { | 290 | while (1) { |
336 | int option_index = 0; | 291 | int option_index = 0; |
337 | c = getopt_long(argc, argv, "hCdvVc:", long_options, &option_index); | 292 | c = getopt_long(argc, argv, "hCdDvVc:", long_options, &option_index); |
338 | if (c == -1) { | 293 | if (c == -1) { |
339 | break; | 294 | break; |
340 | } | 295 | } |
@@ -352,6 +307,9 @@ int main(int argc, char **argv) { | |||
352 | case 'd': // debug | 307 | case 'd': // debug |
353 | debug = 1; | 308 | debug = 1; |
354 | break; | 309 | break; |
310 | case 'D': // extended debug options | ||
311 | enable_debug_tree = true; | ||
312 | break; | ||
355 | case 'v': // version | 313 | case 'v': // version |
356 | fprintf(stdout, "sway version " SWAY_VERSION "\n"); | 314 | fprintf(stdout, "sway version " SWAY_VERSION "\n"); |
357 | exit(EXIT_SUCCESS); | 315 | exit(EXIT_SUCCESS); |
@@ -374,37 +332,24 @@ int main(int argc, char **argv) { | |||
374 | } | 332 | } |
375 | } | 333 | } |
376 | 334 | ||
377 | // we need to setup logging before wlc_init in case it fails. | 335 | // TODO: switch logging over to wlroots? |
378 | if (debug) { | 336 | if (debug) { |
379 | init_log(L_DEBUG); | 337 | wlr_log_init(L_DEBUG, NULL); |
380 | } else if (verbose || validate) { | 338 | } else if (verbose || validate) { |
381 | init_log(L_INFO); | 339 | wlr_log_init(L_INFO, NULL); |
382 | } else { | 340 | } else { |
383 | init_log(L_ERROR); | 341 | wlr_log_init(L_ERROR, NULL); |
384 | } | 342 | } |
385 | 343 | ||
386 | if (optind < argc) { // Behave as IPC client | 344 | if (optind < argc) { // Behave as IPC client |
387 | if(optind != 1) { | 345 | if(optind != 1) { |
388 | sway_log(L_ERROR, "Don't use options with the IPC client"); | 346 | wlr_log(L_ERROR, "Don't use options with the IPC client"); |
389 | exit(EXIT_FAILURE); | ||
390 | } | ||
391 | if (getuid() != geteuid() || getgid() != getegid()) { | ||
392 | if (setgid(getgid()) != 0) { | ||
393 | sway_log(L_ERROR, "Unable to drop root"); | ||
394 | exit(EXIT_FAILURE); | ||
395 | } | ||
396 | if (setuid(getuid()) != 0) { | ||
397 | sway_log(L_ERROR, "Unable to drop root"); | ||
398 | exit(EXIT_FAILURE); | ||
399 | } | ||
400 | } | ||
401 | if (setuid(0) != -1) { | ||
402 | sway_log(L_ERROR, "Root privileges can be restored."); | ||
403 | exit(EXIT_FAILURE); | 347 | exit(EXIT_FAILURE); |
404 | } | 348 | } |
349 | drop_permissions(false); | ||
405 | char *socket_path = getenv("SWAYSOCK"); | 350 | char *socket_path = getenv("SWAYSOCK"); |
406 | if (!socket_path) { | 351 | if (!socket_path) { |
407 | sway_log(L_ERROR, "Unable to retrieve socket path"); | 352 | wlr_log(L_ERROR, "Unable to retrieve socket path"); |
408 | exit(EXIT_FAILURE); | 353 | exit(EXIT_FAILURE); |
409 | } | 354 | } |
410 | char *command = join_args(argv + optind, argc - optind); | 355 | char *command = join_args(argv + optind, argc - optind); |
@@ -413,49 +358,25 @@ int main(int argc, char **argv) { | |||
413 | } | 358 | } |
414 | 359 | ||
415 | executable_sanity_check(); | 360 | executable_sanity_check(); |
416 | #ifdef __linux__ | ||
417 | bool suid = false; | 361 | bool suid = false; |
362 | #ifdef __linux__ | ||
418 | if (getuid() != geteuid() || getgid() != getegid()) { | 363 | if (getuid() != geteuid() || getgid() != getegid()) { |
419 | // Retain capabilities after setuid() | 364 | // Retain capabilities after setuid() |
420 | if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) { | 365 | if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0)) { |
421 | sway_log(L_ERROR, "Cannot keep caps after setuid()"); | 366 | wlr_log(L_ERROR, "Cannot keep caps after setuid()"); |
422 | exit(EXIT_FAILURE); | 367 | exit(EXIT_FAILURE); |
423 | } | 368 | } |
424 | suid = true; | 369 | suid = true; |
425 | } | 370 | } |
426 | #endif | 371 | #endif |
427 | 372 | ||
428 | wlc_log_set_handler(wlc_log_handler); | ||
429 | log_kernel(); | 373 | log_kernel(); |
430 | log_distro(); | 374 | log_distro(); |
431 | log_env(); | ||
432 | detect_proprietary(); | 375 | detect_proprietary(); |
433 | detect_raspi(); | 376 | detect_raspi(); |
434 | 377 | ||
435 | input_devices = create_list(); | ||
436 | |||
437 | /* Changing code earlier than this point requires detailed review */ | ||
438 | /* (That code runs as root on systems without logind, and wlc_init drops to | ||
439 | * another user.) */ | ||
440 | register_wlc_handlers(); | ||
441 | if (!wlc_init()) { | ||
442 | return 1; | ||
443 | } | ||
444 | register_extensions(); | ||
445 | |||
446 | #ifdef __linux__ | 378 | #ifdef __linux__ |
447 | if (suid) { | 379 | drop_permissions(suid); |
448 | // Drop every cap except CAP_SYS_PTRACE | ||
449 | cap_t caps = cap_init(); | ||
450 | cap_value_t keep = CAP_SYS_PTRACE; | ||
451 | sway_log(L_INFO, "Dropping extra capabilities"); | ||
452 | if (cap_set_flag(caps, CAP_PERMITTED, 1, &keep, CAP_SET) || | ||
453 | cap_set_flag(caps, CAP_EFFECTIVE, 1, &keep, CAP_SET) || | ||
454 | cap_set_proc(caps)) { | ||
455 | sway_log(L_ERROR, "Failed to drop extra capabilities"); | ||
456 | exit(EXIT_FAILURE); | ||
457 | } | ||
458 | } | ||
459 | #endif | 380 | #endif |
460 | // handle SIGTERM signals | 381 | // handle SIGTERM signals |
461 | signal(SIGTERM, sig_handler); | 382 | signal(SIGTERM, sig_handler); |
@@ -463,11 +384,16 @@ int main(int argc, char **argv) { | |||
463 | // prevent ipc from crashing sway | 384 | // prevent ipc from crashing sway |
464 | signal(SIGPIPE, SIG_IGN); | 385 | signal(SIGPIPE, SIG_IGN); |
465 | 386 | ||
466 | sway_log(L_INFO, "Starting sway version " SWAY_VERSION "\n"); | 387 | wlr_log(L_INFO, "Starting sway version " SWAY_VERSION); |
388 | |||
389 | layout_init(); | ||
467 | 390 | ||
468 | init_layout(); | 391 | if (!server_init(&server)) { |
392 | return 1; | ||
393 | } | ||
469 | 394 | ||
470 | ipc_init(); | 395 | ipc_init(&server); |
396 | log_env(); | ||
471 | 397 | ||
472 | if (validate) { | 398 | if (validate) { |
473 | bool valid = load_main_config(config_path, false); | 399 | bool valid = load_main_config(config_path, false); |
@@ -484,11 +410,17 @@ int main(int argc, char **argv) { | |||
484 | 410 | ||
485 | security_sanity_check(); | 411 | security_sanity_check(); |
486 | 412 | ||
413 | // TODO: wait for server to be ready | ||
414 | // TODO: consume config->cmd_queue | ||
415 | config->active = true; | ||
416 | |||
487 | if (!terminate_request) { | 417 | if (!terminate_request) { |
488 | wlc_run(); | 418 | server_run(&server); |
489 | } | 419 | } |
490 | 420 | ||
491 | list_free(input_devices); | 421 | wlr_log(L_INFO, "Shutting down sway"); |
422 | |||
423 | server_fini(&server); | ||
492 | 424 | ||
493 | ipc_terminate(); | 425 | ipc_terminate(); |
494 | 426 | ||