aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2024-04-22 12:47:53 +0000
committerWerner Koch <[email protected]>2024-04-22 12:47:53 +0000
commit319a505623c197d06ca3e76f30691fe65a982d6f (patch)
treeca4dfdb7f76a0a389487dcdcd6e70913c72afe47
parentlogging: Indent continuation lines of log_printhex. (diff)
downloadlibgpg-error-319a505623c197d06ca3e76f30691fe65a982d6f.tar.gz
libgpg-error-319a505623c197d06ca3e76f30691fe65a982d6f.zip
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.
-rw-r--r--NEWS5
-rw-r--r--src/gpg-error.def.in2
-rw-r--r--src/gpg-error.h.in3
-rw-r--r--src/gpg-error.vers2
-rw-r--r--src/gpgrt-int.h1
-rw-r--r--src/logging.c67
-rw-r--r--src/visibility.c8
-rw-r--r--src/visibility.h2
8 files changed, 88 insertions, 2 deletions
diff --git a/NEWS b/NEWS
index d532c6d..a41520a 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,11 @@ Noteworthy changes in version 1.49 (unreleased) [C35/A35/R_]
-----------------------------------------------
+ * Interface changes relative to the 1.48 release:
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ gpgrt_add_post_log_func NEW.
+
+
Release-info: https://dev.gnupg.org/T7012
diff --git a/src/gpg-error.def.in b/src/gpg-error.def.in
index 3bd18f7..eab681d 100644
--- a/src/gpg-error.def.in
+++ b/src/gpg-error.def.in
@@ -247,6 +247,6 @@ EXPORTS
;; gpgrt_close_all_fds @188
gpgrt_wipememory @189
-
+ gpgrt_add_post_log_func @190
;; end of file with public symbols for Windows.
diff --git a/src/gpg-error.h.in b/src/gpg-error.h.in
index fcf4eb6..d00bf1b 100644
--- a/src/gpg-error.h.in
+++ b/src/gpg-error.h.in
@@ -995,11 +995,12 @@ enum gpgrt_log_levels
};
-/* The next 4 functions are not thread-safe - call them early. */
+/* The next 5 functions are not thread-safe - call them early. */
void gpgrt_log_set_sink (const char *name, gpgrt_stream_t stream, int fd);
void gpgrt_log_set_socket_dir_cb (const char *(*fnc)(void));
void gpgrt_log_set_pid_suffix_cb (int (*cb)(unsigned long *r_value));
void gpgrt_log_set_prefix (const char *text, unsigned int flags);
+void gpgrt_add_post_log_func (void (*f)(int));
int gpgrt_get_errorcount (int clear);
void gpgrt_inc_errorcount (void);
diff --git a/src/gpg-error.vers b/src/gpg-error.vers
index 78a0ae8..b095edf 100644
--- a/src/gpg-error.vers
+++ b/src/gpg-error.vers
@@ -211,6 +211,8 @@ GPG_ERROR_1.0 {
gpgrt_wipememory;
+ gpgrt_add_post_log_func;
+
local:
*;
};
diff --git a/src/gpgrt-int.h b/src/gpgrt-int.h
index 4ed64be..adddb26 100644
--- a/src/gpgrt-int.h
+++ b/src/gpgrt-int.h
@@ -537,6 +537,7 @@ void _gpgrt_log_set_sink (const char *name, estream_t stream, int fd);
void _gpgrt_log_set_socket_dir_cb (const char *(*fnc)(void));
void _gpgrt_log_set_pid_suffix_cb (int (*cb)(unsigned long *r_value));
void _gpgrt_log_set_prefix (const char *text, unsigned int flags);
+void _gpgrt_add_post_log_func (void (*f)(int));
const char *_gpgrt_log_get_prefix (unsigned int *flags);
int _gpgrt_log_test_fd (int fd);
int _gpgrt_log_get_fd (void);
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. */
diff --git a/src/visibility.c b/src/visibility.c
index 5ecef45..8c00168 100644
--- a/src/visibility.c
+++ b/src/visibility.c
@@ -961,6 +961,14 @@ gpgrt_log_get_stream (void)
return _gpgrt_log_get_stream ();
}
+
+void
+gpgrt_add_post_log_func (void (*f)(int))
+{
+ _gpgrt_add_post_log_func (f);
+}
+
+
void
gpgrt_log (int level, const char *fmt, ...)
{
diff --git a/src/visibility.h b/src/visibility.h
index 75aec0d..8f3bd8c 100644
--- a/src/visibility.h
+++ b/src/visibility.h
@@ -184,6 +184,7 @@ MARK_VISIBLE (gpgrt_log_get_prefix)
MARK_VISIBLE (gpgrt_log_test_fd)
MARK_VISIBLE (gpgrt_log_get_fd)
MARK_VISIBLE (gpgrt_log_get_stream)
+MARK_VISIBLE (gpgrt_add_post_log_func)
MARK_VISIBLE (gpgrt_log)
MARK_VISIBLE (gpgrt_logv)
MARK_VISIBLE (gpgrt_logv_prefix)
@@ -375,6 +376,7 @@ MARK_VISIBLE (gpgrt_absfnameconcat)
#define gpgrt_log_test_fd _gpgrt_USE_UNDERSCORED_FUNCTION
#define gpgrt_log_get_fd _gpgrt_USE_UNDERSCORED_FUNCTION
#define gpgrt_log_get_stream _gpgrt_USE_UNDERSCORED_FUNCTION
+#define gpgrt_add_post_log_func _gpgrt_USE_UNDERSCORED_FUNCTION
#define gpgrt_log _gpgrt_USE_UNDERSCORED_FUNCTION
#define gpgrt_logv _gpgrt_USE_UNDERSCORED_FUNCTION
#define gpgrt_logv_prefix _gpgrt_USE_UNDERSCORED_FUNCTION