Use sigsetjmp to continue cleanup after SIGTERM/SIGINT

This uses the non-local goto sigsetjmp function to continue cleaning
up after a SIGINT or SIGTERM has been caught. Normally, SIGINT or
SIGTERM signal the end of the program and cannot be ignored. We jump
to the cleanup in the signal handler.
This commit is contained in:
Matthew Bauer 2020-05-15 13:39:12 -05:00
parent 6eb693c05b
commit 70ecdcb02e

6
cage.c
View file

@ -12,6 +12,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <getopt.h> #include <getopt.h>
#include <setjmp.h>
#include <signal.h> #include <signal.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -162,6 +163,8 @@ drop_permissions(void)
return true; return true;
} }
sigjmp_buf end_mark;
static int static int
handle_signal(int signal, void *data) handle_signal(int signal, void *data)
{ {
@ -172,6 +175,7 @@ handle_signal(int signal, void *data)
/* Fallthrough */ /* Fallthrough */
case SIGTERM: case SIGTERM:
wl_display_terminate(display); wl_display_terminate(display);
siglongjmp(end_mark, -1);
return 0; return 0;
default: default:
return 0; return 0;
@ -474,6 +478,7 @@ main(int argc, char *argv[])
wlr_xwayland_set_seat(xwayland, server.seat->seat); wlr_xwayland_set_seat(xwayland, server.seat->seat);
#endif #endif
if (sigsetjmp(end_mark, 0) == 0) {
if (!spawn_primary_client(server.wl_display, argv + optind, &pid, &sigchld_source)) { if (!spawn_primary_client(server.wl_display, argv + optind, &pid, &sigchld_source)) {
ret = 1; ret = 1;
goto end; goto end;
@ -484,6 +489,7 @@ main(int argc, char *argv[])
wlr_cursor_warp(server.seat->cursor, NULL, layout_box->width / 2, layout_box->height / 2); wlr_cursor_warp(server.seat->cursor, NULL, layout_box->width / 2, layout_box->height / 2);
wl_display_run(server.wl_display); wl_display_run(server.wl_display);
}
#if CAGE_HAS_XWAYLAND #if CAGE_HAS_XWAYLAND
wlr_xwayland_destroy(xwayland); wlr_xwayland_destroy(xwayland);