changeset 6539:a93a7738c0ec HEAD

Changed failure callbacks to take failure type parameter, so it's no longer necessary to have separate panic and warning callbacks. Added i_log_type() function to log a message with any type (even fatal/panic without dying ourself).
author Timo Sirainen <tss@iki.fi>
date Tue, 09 Oct 2007 17:10:10 +0300
parents 1b7d91f7b151
children 12a779e08a73
files src/lib/failures.c src/lib/failures.h
diffstat 2 files changed, 125 insertions(+), 147 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib/failures.c	Sat Oct 06 03:18:19 2007 +0300
+++ b/src/lib/failures.c	Tue Oct 09 17:10:10 2007 +0300
@@ -13,28 +13,30 @@
 #include <syslog.h>
 #include <time.h>
 
+static const char *log_type_prefixes[] = {
+	"Info: ",
+	"Warning: ",
+	"Error: ",
+	"Fatal: ",
+	"Panic: "
+};
+static char log_type_internal_chars[] = {
+	'I', 'W', 'E', 'F', 'P'
+};
+
 static void failure_exit(int status) ATTR_NORETURN;
 
-static void default_panic_handler(const char *format, va_list args)
-	ATTR_NORETURN ATTR_FORMAT(1, 0);
-static void default_fatal_handler(int status, const char *format, va_list args)
-	ATTR_NORETURN ATTR_FORMAT(2, 0);
-
-static void default_error_handler(const char *format, va_list args)
-	ATTR_FORMAT(1, 0);
-static void default_warning_handler(const char *format, va_list args)
-	ATTR_FORMAT(1, 0);
-static void default_info_handler(const char *format, va_list args)
-	ATTR_FORMAT(1, 0);
+static void default_fatal_handler(enum log_type type, int status,
+				  const char *format, va_list args)
+	ATTR_NORETURN ATTR_FORMAT(3, 0);
+static void default_error_handler(enum log_type type, const char *format,
+				  va_list args) ATTR_FORMAT(2, 0);
 
 /* Initialize working defaults */
-static failure_callback_t *panic_handler ATTR_NORETURN =
-	default_panic_handler;
 static fatal_failure_callback_t *fatal_handler ATTR_NORETURN =
 	default_fatal_handler;
 static failure_callback_t *error_handler = default_error_handler;
-static failure_callback_t *warning_handler = default_warning_handler;
-static failure_callback_t *info_handler = default_info_handler;
+static failure_callback_t *info_handler = default_error_handler;
 static void (*failure_exit_callback)(int *) = NULL;
 
 static FILE *log_fd = NULL, *log_info_fd = NULL;
@@ -125,17 +127,6 @@
 	return 0;
 }
 
-static void ATTR_FORMAT(1, 0)
-default_panic_handler(const char *format, va_list args)
-{
-	const char *backtrace;
-
-	(void)default_handler("Panic: ", log_fd, format, args);
-	if (backtrace_get(&backtrace) == 0)
-		i_error("Raw backtrace: %s", backtrace);
-	abort();
-}
-
 static void log_fd_flush_stop(struct ioloop *ioloop)
 {
 	io_loop_stop(ioloop);
@@ -155,7 +146,7 @@
 		/* wait until we can write more. this can happen at least
 		   when writing to terminal, even if fd is blocking. */
 		ioloop = io_loop_create();
-		io = io_add(IO_WRITE, fileno(log_fd),
+		io = io_add(IO_WRITE, fileno(fd),
 			    log_fd_flush_stop, ioloop);
 		io_loop_run(ioloop);
 		io_remove(&io);
@@ -164,45 +155,52 @@
 	return 0;
 }
 
-static void ATTR_FORMAT(2, 0)
-default_fatal_handler(int status, const char *format, va_list args)
+static void ATTR_FORMAT(3, 0)
+default_fatal_handler(enum log_type type, int status,
+		      const char *format, va_list args)
 {
-	if (default_handler("Fatal: ", log_fd, format, args) < 0 &&
-	    status == FATAL_DEFAULT)
+	const char *backtrace;
+
+	if (default_handler(log_type_prefixes[type], log_fd, format,
+			    args) < 0 && status == FATAL_DEFAULT)
 		status = FATAL_LOGERROR;
 
+	if (type == LOG_TYPE_PANIC) {
+		if (backtrace_get(&backtrace) == 0)
+			i_error("Raw backtrace: %s", backtrace);
+	}
+
 	if (log_fd_flush(log_fd) < 0 && status == FATAL_DEFAULT)
 		status = FATAL_LOGWRITE;
 
-	failure_exit(status);
+	if (type == LOG_TYPE_PANIC)
+		abort();
+	else
+		failure_exit(status);
 }
 
-static void ATTR_FORMAT(1, 0)
-default_error_handler(const char *format, va_list args)
+static void ATTR_FORMAT(2, 0)
+default_error_handler(enum log_type type, const char *format, va_list args)
 {
-	if (default_handler("Error: ", log_fd, format, args) < 0)
+	FILE *fd = type == LOG_TYPE_INFO ? log_info_fd : log_fd;
+
+	if (default_handler(log_type_prefixes[type], fd, format, args) < 0)
 		failure_exit(FATAL_LOGERROR);
 
-	if (log_fd_flush(log_fd) < 0)
+	if (log_fd_flush(fd) < 0)
 		failure_exit(FATAL_LOGWRITE);
 }
 
-static void ATTR_FORMAT(1, 0)
-default_warning_handler(const char *format, va_list args)
+void i_log_type(enum log_type type, const char *format, ...)
 {
-	(void)default_handler("Warning: ", log_fd, format, args);
+	va_list args;
 
-	if (log_fd_flush(log_fd) < 0)
-		failure_exit(FATAL_LOGWRITE);
-}
-
-static void ATTR_FORMAT(1, 0)
-default_info_handler(const char *format, va_list args)
-{
-	(void)default_handler("Info: ", log_info_fd, format, args);
-
-	if (log_fd_flush(log_info_fd) < 0)
-		failure_exit(FATAL_LOGWRITE);
+	va_start(args, format);
+	if (type == LOG_TYPE_INFO)
+		info_handler(type, format, args);
+	else
+		error_handler(type, format, args);
+	va_end(args);
 }
 
 void i_panic(const char *format, ...)
@@ -210,7 +208,7 @@
 	va_list args;
 
 	va_start(args, format);
-	panic_handler(format, args);
+	fatal_handler(LOG_TYPE_PANIC, 0, format, args);
 	va_end(args);
 }
 
@@ -219,7 +217,7 @@
 	va_list args;
 
 	va_start(args, format);
-	fatal_handler(FATAL_DEFAULT, format, args);
+	fatal_handler(LOG_TYPE_FATAL, FATAL_DEFAULT, format, args);
 	va_end(args);
 }
 
@@ -228,7 +226,7 @@
 	va_list args;
 
 	va_start(args, format);
-	fatal_handler(status, format, args);
+	fatal_handler(LOG_TYPE_FATAL, status, format, args);
 	va_end(args);
 }
 
@@ -238,7 +236,7 @@
 	va_list args;
 
 	va_start(args, format);
-	error_handler(format, args);
+	error_handler(LOG_TYPE_ERROR, format, args);
 	va_end(args);
 
 	errno = old_errno;
@@ -250,7 +248,7 @@
 	va_list args;
 
 	va_start(args, format);
-	warning_handler(format, args);
+	error_handler(LOG_TYPE_WARNING, format, args);
 	va_end(args);
 
 	errno = old_errno;
@@ -262,19 +260,12 @@
 	va_list args;
 
 	va_start(args, format);
-	info_handler(format, args);
+	info_handler(LOG_TYPE_INFO, format, args);
 	va_end(args);
 
 	errno = old_errno;
 }
 
-void i_set_panic_handler(failure_callback_t *callback ATTR_NORETURN)
-{
-	if (callback == NULL)
-		callback = default_panic_handler;
-        panic_handler = callback;
-}
-
 void i_set_fatal_handler(fatal_failure_callback_t *callback ATTR_NORETURN)
 {
 	if (callback == NULL)
@@ -286,21 +277,14 @@
 {
 	if (callback == NULL)
 		callback = default_error_handler;
-        error_handler = callback;
-}
-
-void i_set_warning_handler(failure_callback_t *callback)
-{
-	if (callback == NULL)
-		callback = default_warning_handler;
-        warning_handler = callback;
+	error_handler = callback;
 }
 
 void i_set_info_handler(failure_callback_t *callback)
 {
 	if (callback == NULL)
-		callback = default_info_handler;
-        info_handler = callback;
+		callback = default_error_handler;
+	info_handler = callback;
 }
 
 static int ATTR_FORMAT(2, 0)
@@ -321,48 +305,53 @@
 	return 0;
 }
 
-void i_syslog_panic_handler(const char *fmt, va_list args)
+void i_syslog_fatal_handler(enum log_type type, int status,
+			    const char *fmt, va_list args)
 {
 	const char *backtrace;
-
-	(void)syslog_handler(LOG_CRIT, fmt, args);
-	if (backtrace_get(&backtrace) == 0)
-		i_error("Raw backtrace: %s", backtrace);
-	abort();
-}
-
-void i_syslog_fatal_handler(int status, const char *fmt, va_list args)
-{
 	if (syslog_handler(LOG_CRIT, fmt, args) < 0 && status == FATAL_DEFAULT)
 		status = FATAL_LOGERROR;
-	failure_exit(status);
-}
 
-void i_syslog_error_handler(const char *fmt, va_list args)
-{
-	if (syslog_handler(LOG_ERR, fmt, args) < 0)
-		failure_exit(FATAL_LOGERROR);
+	if (type == LOG_TYPE_PANIC) {
+		if (backtrace_get(&backtrace) == 0)
+			i_error("Raw backtrace: %s", backtrace);
+		abort();
+	} else {
+		failure_exit(status);
+	}
 }
 
-void i_syslog_warning_handler(const char *fmt, va_list args)
+void i_syslog_error_handler(enum log_type type, const char *fmt, va_list args)
 {
-	(void)syslog_handler(LOG_WARNING, fmt, args);
-}
+	int level = LOG_ERR;
 
-void i_syslog_info_handler(const char *fmt, va_list args)
-{
-	(void)syslog_handler(LOG_INFO, fmt, args);
+	switch (type) {
+	case LOG_TYPE_INFO:
+		level = LOG_INFO;
+		break;
+	case LOG_TYPE_WARNING:
+		level = LOG_WARNING;
+		break;
+	case LOG_TYPE_ERROR:
+		level = LOG_ERR;
+		break;
+	case LOG_TYPE_FATAL:
+	case LOG_TYPE_PANIC:
+		level = LOG_CRIT;
+		break;
+	}
+
+	if (syslog_handler(level, fmt, args) < 0)
+		failure_exit(FATAL_LOGERROR);
 }
 
 void i_set_failure_syslog(const char *ident, int options, int facility)
 {
 	openlog(ident, options, facility);
 
-	i_set_panic_handler(i_syslog_panic_handler);
 	i_set_fatal_handler(i_syslog_fatal_handler);
 	i_set_error_handler(i_syslog_error_handler);
-	i_set_warning_handler(i_syslog_warning_handler);
-	i_set_info_handler(i_syslog_info_handler);
+	i_set_info_handler(i_syslog_error_handler);
 }
 
 static void open_log_file(FILE **file, const char *path)
@@ -394,10 +383,9 @@
 	open_log_file(&log_fd, path);
 	log_info_fd = log_fd;
 
-	i_set_panic_handler(NULL);
 	i_set_fatal_handler(NULL);
 	i_set_error_handler(NULL);
-	i_set_warning_handler(NULL);
+	i_set_info_handler(NULL);
 }
 
 void i_set_failure_prefix(const char *prefix)
@@ -424,51 +412,37 @@
 	return ret;
 }
 
-static void ATTR_NORETURN ATTR_FORMAT(1, 0)
-i_internal_panic_handler(const char *fmt, va_list args)
+static void ATTR_NORETURN ATTR_FORMAT(3, 0)
+i_internal_fatal_handler(enum log_type type, int status,
+			 const char *fmt, va_list args)
 {
 	const char *backtrace;
 
-	(void)internal_handler('F', fmt, args);
-	if (backtrace_get(&backtrace) == 0)
-		i_error("Raw backtrace: %s", backtrace);
-        abort();
-}
+	if (internal_handler(log_type_internal_chars[type], fmt, args) < 0 &&
+	    status == FATAL_DEFAULT)
+		status = FATAL_LOGERROR;
 
-static void ATTR_NORETURN ATTR_FORMAT(2, 0)
-i_internal_fatal_handler(int status, const char *fmt, va_list args)
-{
-	if (internal_handler('F', fmt, args) < 0 && status == FATAL_DEFAULT)
-		status = FATAL_LOGERROR;
-	failure_exit(status);
+	if (type == LOG_TYPE_PANIC) {
+		if (backtrace_get(&backtrace) == 0)
+			i_error("Raw backtrace: %s", backtrace);
+		abort();
+	} else {
+		failure_exit(status);
+	}
 }
 
-static void ATTR_FORMAT(1, 0)
-i_internal_error_handler(const char *fmt, va_list args)
+static void ATTR_FORMAT(2, 0)
+i_internal_error_handler(enum log_type type, const char *fmt, va_list args)
 {
-	if (internal_handler('E', fmt, args) < 0)
+	if (internal_handler(log_type_internal_chars[type], fmt, args) < 0)
 		failure_exit(FATAL_LOGERROR);
 }
 
-static void ATTR_FORMAT(1, 0)
-i_internal_warning_handler(const char *fmt, va_list args)
-{
-	(void)internal_handler('W', fmt, args);
-}
-
-static void ATTR_FORMAT(1, 0)
-i_internal_info_handler(const char *fmt, va_list args)
-{
-	(void)internal_handler('I', fmt, args);
-}
-
 void i_set_failure_internal(void)
 {
-	i_set_panic_handler(i_internal_panic_handler);
 	i_set_fatal_handler(i_internal_fatal_handler);
 	i_set_error_handler(i_internal_error_handler);
-	i_set_warning_handler(i_internal_warning_handler);
-	i_set_info_handler(i_internal_info_handler);
+	i_set_info_handler(i_internal_error_handler);
 }
 
 void i_set_info_file(const char *path)
@@ -477,7 +451,7 @@
 		log_info_fd = NULL;
 
 	open_log_file(&log_info_fd, path);
-        info_handler = default_info_handler;
+        info_handler = default_error_handler;
 }
 
 void i_set_failure_timestamp_format(const char *fmt)
--- a/src/lib/failures.h	Sat Oct 06 03:18:19 2007 +0300
+++ b/src/lib/failures.h	Tue Oct 09 17:10:10 2007 +0300
@@ -12,10 +12,21 @@
 	FATAL_DEFAULT	= 89
 };
 
+enum log_type {
+	LOG_TYPE_INFO,
+	LOG_TYPE_WARNING,
+	LOG_TYPE_ERROR,
+	LOG_TYPE_FATAL,
+	LOG_TYPE_PANIC
+};
+
 #define DEFAULT_FAILURE_STAMP_FORMAT "%b %d %H:%M:%S "
 
-typedef void failure_callback_t(const char *, va_list);
-typedef void fatal_failure_callback_t(int status, const char *, va_list);
+typedef void failure_callback_t(enum log_type type, const char *, va_list);
+typedef void fatal_failure_callback_t(enum log_type type, int status,
+				      const char *, va_list);
+
+void i_log_type(enum log_type type, const char *format, ...) ATTR_FORMAT(2, 3);
 
 void i_panic(const char *format, ...) ATTR_FORMAT(1, 2) ATTR_NORETURN;
 void i_fatal(const char *format, ...) ATTR_FORMAT(1, 2) ATTR_NORETURN;
@@ -26,24 +37,17 @@
 void i_fatal_status(int status, const char *format, ...)
 	ATTR_FORMAT(2, 3) ATTR_NORETURN;
 
-/* Change failure handlers. Make sure they don't modify errno. */
-void i_set_panic_handler(failure_callback_t *callback ATTR_NORETURN);
+/* Change failure handlers. */
 void i_set_fatal_handler(fatal_failure_callback_t *callback ATTR_NORETURN);
 void i_set_error_handler(failure_callback_t *callback);
-void i_set_warning_handler(failure_callback_t *callback);
 void i_set_info_handler(failure_callback_t *callback);
 
 /* Send failures to syslog() */
-void i_syslog_panic_handler(const char *fmt, va_list args)
-	ATTR_NORETURN ATTR_FORMAT(1, 0);
-void i_syslog_fatal_handler(int status, const char *fmt, va_list args)
-	ATTR_NORETURN ATTR_FORMAT(2, 0);
-void i_syslog_error_handler(const char *fmt, va_list args)
-	ATTR_FORMAT(1, 0);
-void i_syslog_warning_handler(const char *fmt, va_list args)
-	ATTR_FORMAT(1, 0);
-void i_syslog_info_handler(const char *fmt, va_list args)
-	ATTR_FORMAT(1, 0);
+void i_syslog_fatal_handler(enum log_type type, int status,
+			    const char *fmt, va_list args)
+	ATTR_NORETURN ATTR_FORMAT(3, 0);
+void i_syslog_error_handler(enum log_type type, const char *fmt, va_list args)
+	ATTR_FORMAT(2, 0);
 
 /* Open syslog and set failure/info handlers to use it. */
 void i_set_failure_syslog(const char *ident, int options, int facility);