From d07db5494d0641ceb5de3d91052949f65dece46b Mon Sep 17 00:00:00 2001 From: Alberto Leiva Popper Date: Wed, 16 Oct 2024 13:43:42 -0600 Subject: [PATCH] Atomize output files I feel like I need to relearn signals every time I have to interact with them. Best get this done while the iron's hot. 1. The ROA file is first written as `/.roa`. The RK file is first written as `/.rk`. 2. When the validation run is done, `.roa` is renamed to `--output.roa`, and `.rk` becomes `--output.bgpsec`. 3. Most terminating signals unlink `.roa` and `.rk`. Fixes #124. --- src/main.c | 6 +++++- src/output_printer.c | 47 ++++++++++++++++++++++++++++++++++++++------ src/output_printer.h | 2 ++ src/sig.c | 2 ++ 4 files changed, 50 insertions(+), 7 deletions(-) diff --git a/src/main.c b/src/main.c index 014a1afc..ee61d7d6 100644 --- a/src/main.c +++ b/src/main.c @@ -7,6 +7,7 @@ #include "http.h" #include "log.h" #include "nid.h" +#include "output_printer.h" #include "print_file.h" #include "relax_ng.h" #include "rtr/rtr.h" @@ -153,6 +154,9 @@ main(int argc, char **argv) error = cache_setup(); if (error) goto revert_vrps; + error = output_setup(); + if (error) + goto revert_cache; /* Meat */ @@ -169,7 +173,7 @@ main(int argc, char **argv) } /* End */ - +revert_cache: cache_teardown(); revert_vrps: vrps_destroy(); diff --git a/src/output_printer.c b/src/output_printer.c index c9ecaf9f..3b5e10f2 100644 --- a/src/output_printer.c +++ b/src/output_printer.c @@ -10,8 +10,27 @@ typedef struct json_out { bool first; } JSON_OUT; +int +output_setup(void) +{ + int err1; + int err2; + + errno = 0; + err1 = atexit(output_atexit); + if (err1) { + err2 = errno; + pr_op_err("Cannot register output's exit function."); + pr_op_err("Error message attempt 1: %s", strerror(err1)); + pr_op_err("Error message attempt 2: %s", strerror(err2)); + return err1; + } + + return 0; +} + static FILE * -load_output_file(char const *filename) +load_output_file(char const *filename, char const *tmpname) { FILE *out; @@ -21,7 +40,7 @@ load_output_file(char const *filename) if (strcmp(filename, "-") == 0) return stdout; - return (file_write(filename, "w", &out) == 0) ? out : NULL; + return (file_write(tmpname, "w", &out) == 0) ? out : NULL; } static int @@ -130,7 +149,7 @@ print_roas(struct db_table const *db) JSON_OUT json_out; int error; - out = load_output_file(config_get_output_roa()); + out = load_output_file(config_get_output_roa(), ".roa"); if (out == NULL) return; @@ -149,8 +168,12 @@ print_roas(struct db_table const *db) if (error) pr_op_err("Error printing ROAs: %s", strerror(error)); - if (out != stdout) + if (out != stdout) { file_close(out); + if (!error && rename(".roa", config_get_output_roa()) < 0) + pr_op_err("Cannot move '.roa' to '%s': %s", + config_get_output_roa(), strerror(errno)); + } } static void @@ -160,7 +183,7 @@ print_router_keys(struct db_table const *db) JSON_OUT json_out; int error; - out = load_output_file(config_get_output_bgpsec()); + out = load_output_file(config_get_output_bgpsec(), ".rk"); if (out == NULL) return; @@ -179,8 +202,12 @@ print_router_keys(struct db_table const *db) if (error) pr_op_err("Error printing Router Keys: %s", strerror(error)); - if (out != stdout) + if (out != stdout) { file_close(out); + if (!error && rename(".rk", config_get_output_bgpsec()) < 0) + pr_op_err("Cannot move '.rk' to '%s': %s", + config_get_output_bgpsec(), strerror(errno)); + } } void @@ -189,3 +216,11 @@ output_print_data(struct db_table const *db) print_roas(db); print_router_keys(db); } + +/* THIS FUNCTION CAN BE CALLED FROM A SIGNAL HANDLER. */ +void +output_atexit(void) +{ + unlink(".roa"); + unlink(".rk"); +} diff --git a/src/output_printer.h b/src/output_printer.h index 92b5b6a1..35daaedf 100644 --- a/src/output_printer.h +++ b/src/output_printer.h @@ -3,6 +3,8 @@ #include "rtr/db/db_table.h" +int output_setup(void); void output_print_data(struct db_table const *); +void output_atexit(void); #endif /* SRC_OUTPUT_PRINTER_H_ */ diff --git a/src/sig.c b/src/sig.c index daa7e376..9df78b18 100644 --- a/src/sig.c +++ b/src/sig.c @@ -12,6 +12,7 @@ #include "cache.h" #include "log.h" +#include "output_printer.h" /* * Ensures libgcc is loaded; otherwise backtrace() might allocate @@ -55,6 +56,7 @@ do_cleanup(int signum) print_stack_trace(); cache_atexit(); + output_atexit(); /* Trigger default handler */ signal(signum, SIG_DFL); -- 2.47.2