From 319a505623c197d06ca3e76f30691fe65a982d6f Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 22 Apr 2024 14:47:53 +0200 Subject: core: New function gpgrt_add_post_log_func. * src/gpg-error.h.in (gpgrt_add_post_log_func): New. * src/gpg-error.vers: Add new function * src/gpg-error.def.in: Ditto. * src/visibility.c (gpgrt_add_post_log_func): New. * src/logging.c (struct post_log_func_item_s): New. (post_log_func_list): New. (_gpgrt_add_post_log_func): new. (run_post_log_funcs): New. (_gpgrt_logv_internal): Call for fatal and bug log levels. -- This is required in case an application or library needs to do do some quick cleanups after a log_fatal. --- src/logging.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) (limited to 'src/logging.c') diff --git a/src/logging.c b/src/logging.c index 4dc0eba..4f52d80 100644 --- a/src/logging.c +++ b/src/logging.c @@ -101,6 +101,18 @@ static int force_prefixes; static int missing_lf; static int errorcount; +/* The list of registered functions to be called after logging. */ +struct post_log_func_item_s; +typedef struct post_log_func_item_s *post_log_func_item_t; +struct post_log_func_item_s +{ + post_log_func_item_t next; + void (*func) (int); +}; +static post_log_func_item_t post_log_func_list; + + + /* An object to convey data to the fmt_string_filter. */ struct fmt_string_filter_s @@ -655,6 +667,59 @@ _gpgrt_log_get_stream (void) } +/* Add a function F to the list of functions called after a log_fatal + * or log_bug right before terminating the process. If a function + * with that address has already been registered, it is not added a + * second time. */ +void +_gpgrt_add_post_log_func (void (*f)(int)) +{ + post_log_func_item_t item; + + for (item = post_log_func_list; item; item = item->next) + if (item->func == f) + return; /* Function has already been registered. */ + + /* We use a standard malloc here. */ + item = malloc (sizeof *item); + if (item) + { + item->func = f; + item->next = post_log_func_list; + post_log_func_list = item; + } + else + _gpgrt_log_fatal ("out of core in gpgrt_add_post_log_func\n"); +} + + +/* Run the post log function handlers. These are only called for + * fatal and bug errors and should be aware that the process will + * terminate. */ +static void +run_post_log_funcs (int level) +{ + static int running; /* Just to avoid recursive calls. */ + post_log_func_item_t next; + void (*f)(int); + + if (running) + return; + running = 1; + + while (post_log_func_list) + { + next = post_log_func_list->next; + f = post_log_func_list->func; + post_log_func_list->func = NULL; + post_log_func_list = next; + if (f) + f (level); + } +} + + + /* A filter used with the fprintf_sf function to sanitize the args for * "%s" format specifiers. */ static char * @@ -983,6 +1048,7 @@ _gpgrt_logv_internal (int level, int ignore_arg_ptr, const char *extrastring, { if (missing_lf) _gpgrt_putc_unlocked ('\n', logstream); + run_post_log_funcs (level); _gpgrt_funlockfile (logstream); exit (2); } @@ -990,6 +1056,7 @@ _gpgrt_logv_internal (int level, int ignore_arg_ptr, const char *extrastring, { if (missing_lf) _gpgrt_putc_unlocked ('\n', logstream ); + run_post_log_funcs (level); _gpgrt_funlockfile (logstream); /* Using backtrace requires a configure test and to pass * -rdynamic to gcc. Thus we do not enable it now. */ -- cgit v1.2.3