anastasis

Credential backup and recovery protocol and service
Log | Files | Refs | Submodules | README | LICENSE

commit 12a42b8afec72e902bea707f8d5083f08ab2cac3
parent d8d8258d6407a1c39ca5d889f01f27dfa386a197
Author: Christian Grothoff <christian@grothoff.org>
Date:   Tue,  4 Aug 2026 15:21:48 +0200

fix return value from main to not be 0 on failure

Diffstat:
Msrc/cli/anastasis-cli-redux.c | 54+++++++++++++++++++++++++++++++++++++-----------------
1 file changed, 37 insertions(+), 17 deletions(-)

diff --git a/src/cli/anastasis-cli-redux.c b/src/cli/anastasis-cli-redux.c @@ -83,9 +83,11 @@ static json_t *arguments; static struct ANASTASIS_ReduxAction *ra; /** - * Return value from main. + * Return value from main. Defaults to failure so that every path which shuts + * down without an action having run to completion — a parse error, a bad + * command line, or a signal — is reported to the caller's shell. */ -static int global_ret; +static int global_ret = 1; /** @@ -93,8 +95,9 @@ static int global_ret; * * @param state to persist * @param filename where to write the state to, NULL for stdout + * @return #GNUNET_OK if the state was written out */ -static void +static enum GNUNET_GenericReturnValue persist_new_state (json_t *state, const char *filename) { @@ -108,10 +111,9 @@ persist_new_state (json_t *state, GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not dump state to `%s'\n", filename); - global_ret = 1; - return; + return GNUNET_SYSERR; } - return; + return GNUNET_OK; } { char *state_str = json_dumps (state, @@ -121,8 +123,7 @@ persist_new_state (json_t *state, { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not serialize state to JSON\n"); - global_ret = 1; - return; + return GNUNET_SYSERR; } if (-1 >= fprintf (stdout, @@ -131,12 +132,20 @@ persist_new_state (json_t *state, { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not dump state to stdout\n"); - global_ret = 1; GNUNET_free (state_str); - return; + return GNUNET_SYSERR; } GNUNET_free (state_str); + /* stdio may only report a full output device at flush time, and the + implicit flush at exit has nowhere left to report it to. */ + if (0 != fflush (stdout)) + { + GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, + "fflush"); + return GNUNET_SYSERR; + } } + return GNUNET_OK; } @@ -152,11 +161,19 @@ action_cb (void *cls, enum TALER_ErrorCode error_code, json_t *result_state) { + bool persisted = true; + (void) cls; ra = NULL; if (NULL != result_state) - persist_new_state (result_state, - output_filename); + persisted = (GNUNET_OK == + persist_new_state (result_state, + output_filename)); + /* A state we could not write out is a failure of this tool even when the + reduction itself succeeded, so both conditions must hold. */ + if ( (TALER_EC_NONE == error_code) && + persisted) + global_ret = 0; if (TALER_EC_NONE != error_code) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -168,7 +185,6 @@ action_cb (void *cls, JSON_INDENT (2)); } GNUNET_SCHEDULER_shutdown (); - global_ret = (TALER_EC_NONE != error_code) ? 1 : 0; } @@ -251,8 +267,10 @@ run (void *cls, GNUNET_SCHEDULER_shutdown (); return; } - persist_new_state (init_state, - args[0]); + if (GNUNET_OK == + persist_new_state (init_state, + args[0])) + global_ret = 0; json_decref (init_state); GNUNET_SCHEDULER_shutdown (); return; @@ -270,8 +288,10 @@ run (void *cls, GNUNET_SCHEDULER_shutdown (); return; } - persist_new_state (init_state, - args[0]); + if (GNUNET_OK == + persist_new_state (init_state, + args[0])) + global_ret = 0; json_decref (init_state); GNUNET_SCHEDULER_shutdown (); return;