From b904d15290d14d276062bddcb261e7f986fa6fcc Mon Sep 17 00:00:00 2001 From: Patrick Steinhardt Date: Wed, 16 Sep 2020 20:26:39 +0200 Subject: [PATCH] cage: optionally return exitcode of primary client Some applications indicate different shutdown conditions by returning specific exit codes. One of these is e.g. Kodi, which returns 64 in case the user chose "Power off" and 66 in case the user chose "Reboot". In order to act on these exit codes, it thus makes sense in some situations to pass them on from the primary client to the caller of Cage. Add a new flag "-e". If it's set and Cage shutso down because of an orderly exit of its primary client, then it causes Cage to return the primary client's exit code instead of its own one. --- cage.1.scd | 6 +++++- cage.c | 19 ++++++++++++++----- server.h | 1 + 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/cage.1.scd b/cage.1.scd index 4ca1bea..d33f62a 100644 --- a/cage.1.scd +++ b/cage.1.scd @@ -6,7 +6,7 @@ cage - a Wayland kiosk compositor # SYNOPSIS -*cage* [-dhmrsv] [--] _application_ [application argument ...] +*cage* [-dehmrsv] [--] _application_ [application argument ...] # DESCRIPTION @@ -19,6 +19,10 @@ activities outside the scope of the running application are prevented. *-d* Don't draw client side decorations when possible. +*-e* + Return the primary client's exit code if Cage shuts down because of the + client exiting. + *-h* Show the help message. diff --git a/cage.c b/cage.c index b8e76d6..9ea46a5 100644 --- a/cage.c +++ b/cage.c @@ -128,7 +128,7 @@ spawn_primary_client(struct wl_display *display, char *argv[], pid_t *pid_out, s return true; } -static void +static int cleanup_primary_client(pid_t pid) { int status; @@ -137,9 +137,12 @@ cleanup_primary_client(pid_t pid) if (WIFEXITED(status)) { wlr_log(WLR_DEBUG, "Child exited normally with exit status %d", WEXITSTATUS(status)); + return WEXITSTATUS(status); } else if (WIFSIGNALED(status)) { wlr_log(WLR_DEBUG, "Child was terminated by a signal (%d)", WTERMSIG(status)); } + + return 0; } static bool @@ -188,6 +191,7 @@ usage(FILE *file, const char *cage) #ifdef DEBUG " -D\t Turn on damage tracking debugging\n" #endif + " -e\t Return application's exit code if it exited normally\n" " -h\t Display this help message\n" " -m extend Extend the display across all connected outputs (default)\n" " -m last Use only the last connected output\n" @@ -204,9 +208,9 @@ parse_args(struct cg_server *server, int argc, char *argv[]) { int c; #ifdef DEBUG - while ((c = getopt(argc, argv, "dDhm:rsv")) != -1) { + while ((c = getopt(argc, argv, "dDehm:rsv")) != -1) { #else - while ((c = getopt(argc, argv, "dhm:rsv")) != -1) { + while ((c = getopt(argc, argv, "dhem:rsv")) != -1) { #endif switch (c) { case 'd': @@ -217,6 +221,9 @@ parse_args(struct cg_server *server, int argc, char *argv[]) server->debug_damage_tracking = true; break; #endif + case 'e': + server->return_app_code = true; + break; case 'h': usage(stdout, argv[0]); return false; @@ -276,7 +283,7 @@ main(int argc, char *argv[]) struct wlr_xcursor_manager *xcursor_manager = NULL; #endif pid_t pid = 0; - int ret = 0; + int ret = 0, app_ret = 0; if (!parse_args(&server, argc, argv)) { return 1; @@ -504,7 +511,9 @@ main(int argc, char *argv[]) wl_display_destroy_clients(server.wl_display); end: - cleanup_primary_client(pid); + app_ret = cleanup_primary_client(pid); + if (!ret && server.return_app_code) + ret = app_ret; wl_event_source_remove(sigint_source); wl_event_source_remove(sigterm_source); diff --git a/server.h b/server.h index 817637b..ce252aa 100644 --- a/server.h +++ b/server.h @@ -51,6 +51,7 @@ struct cg_server { #ifdef DEBUG bool debug_damage_tracking; #endif + bool return_app_code; }; #endif