diff options
Diffstat (limited to 'src/shared/main-func.h')
-rw-r--r-- | src/shared/main-func.h | 49 |
1 files changed, 44 insertions, 5 deletions
diff --git a/src/shared/main-func.h b/src/shared/main-func.h index 3f6b6a8..d0689b4 100644 --- a/src/shared/main-func.h +++ b/src/shared/main-func.h @@ -3,16 +3,22 @@ #include <stdlib.h> +#if HAVE_VALGRIND_VALGRIND_H +# include <valgrind/valgrind.h> +#endif + #include "sd-daemon.h" #include "argv-util.h" +#include "hashmap.h" #include "pager.h" #include "selinux-util.h" +#include "signal-util.h" #include "spawn-ask-password-agent.h" #include "spawn-polkit-agent.h" #include "static-destruct.h" -#define _DEFINE_MAIN_FUNCTION(intro, impl, ret) \ +#define _DEFINE_MAIN_FUNCTION(intro, impl, result_to_exit_status, result_to_return_value) \ int main(int argc, char *argv[]) { \ int r; \ assert_se(argc > 0 && !isempty(argv[0])); \ @@ -21,22 +27,55 @@ r = impl; \ if (r < 0) \ (void) sd_notifyf(0, "ERRNO=%i", -r); \ - (void) sd_notifyf(0, "EXIT_STATUS=%i", ret); \ + (void) sd_notifyf(0, "EXIT_STATUS=%i", \ + result_to_exit_status(r)); \ ask_password_agent_close(); \ polkit_agent_close(); \ pager_close(); \ mac_selinux_finish(); \ static_destruct(); \ - return ret; \ + return result_to_return_value(r); \ } +static inline int exit_failure_if_negative(int result) { + return result < 0 ? EXIT_FAILURE : EXIT_SUCCESS; +} + /* Negative return values from impl are mapped to EXIT_FAILURE, and * everything else means success! */ #define DEFINE_MAIN_FUNCTION(impl) \ - _DEFINE_MAIN_FUNCTION(,impl(argc, argv), r < 0 ? EXIT_FAILURE : EXIT_SUCCESS) + _DEFINE_MAIN_FUNCTION(,impl(argc, argv), exit_failure_if_negative, exit_failure_if_negative) + +static inline int exit_failure_if_nonzero(int result) { + return result < 0 ? EXIT_FAILURE : result; +} /* Zero is mapped to EXIT_SUCCESS, negative values are mapped to EXIT_FAILURE, * and positive values are propagated. * Note: "true" means failure! */ #define DEFINE_MAIN_FUNCTION_WITH_POSITIVE_FAILURE(impl) \ - _DEFINE_MAIN_FUNCTION(,impl(argc, argv), r < 0 ? EXIT_FAILURE : r) + _DEFINE_MAIN_FUNCTION(,impl(argc, argv), exit_failure_if_nonzero, exit_failure_if_nonzero) + +static inline int raise_or_exit_status(int ret) { + if (ret < 0) + return EXIT_FAILURE; + if (ret == 0) + return EXIT_SUCCESS; + if (!SIGNAL_VALID(ret)) + return EXIT_FAILURE; + +#if HAVE_VALGRIND_VALGRIND_H + /* If raise() below succeeds, the destructor cleanup_pools() in hashmap.c will never called. */ + if (RUNNING_ON_VALGRIND) + hashmap_trim_pools(); +#endif + + (void) raise(ret); + /* exit with failure if raise() does not immediately abort the program. */ + return EXIT_FAILURE; +} + +/* Negative return values from impl are mapped to EXIT_FAILURE, zero is mapped to EXIT_SUCCESS, + * and raise if a positive signal is returned from impl. */ +#define DEFINE_MAIN_FUNCTION_WITH_POSITIVE_SIGNAL(impl) \ + _DEFINE_MAIN_FUNCTION(,impl(argc, argv), exit_failure_if_negative, raise_or_exit_status) |