summaryrefslogtreecommitdiffstats
path: root/src/lib/failures.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/failures.h')
-rw-r--r--src/lib/failures.h157
1 files changed, 157 insertions, 0 deletions
diff --git a/src/lib/failures.h b/src/lib/failures.h
new file mode 100644
index 0000000..afb4c6f
--- /dev/null
+++ b/src/lib/failures.h
@@ -0,0 +1,157 @@
+#ifndef FAILURES_H
+#define FAILURES_H
+
+struct ip_addr;
+
+/* Default exit status codes that we could use. */
+enum fatal_exit_status {
+ FATAL_LOGOPEN = 80, /* Can't open log file */
+ FATAL_LOGWRITE = 81, /* Can't write to log file */
+ FATAL_LOGERROR = 82, /* Internal logging error */
+ FATAL_OUTOFMEM = 83, /* Out of memory */
+ FATAL_EXEC = 84, /* exec() failed */
+
+ FATAL_DEFAULT = 89
+};
+
+enum log_type {
+ LOG_TYPE_DEBUG,
+ LOG_TYPE_INFO,
+ LOG_TYPE_WARNING,
+ LOG_TYPE_ERROR,
+ LOG_TYPE_FATAL,
+ LOG_TYPE_PANIC,
+
+ LOG_TYPE_COUNT,
+ /* special case */
+ LOG_TYPE_OPTION
+};
+
+struct failure_line {
+ pid_t pid;
+ enum log_type log_type;
+ /* If non-zero, the first log_prefix_len bytes in text indicate
+ the log prefix. This implies disable_log_prefix=TRUE. */
+ unsigned int log_prefix_len;
+ /* Disable the global log prefix. */
+ bool disable_log_prefix;
+ const char *text;
+};
+
+struct failure_context {
+ enum log_type type;
+ int exit_status; /* for LOG_TYPE_FATAL */
+ const struct tm *timestamp; /* NULL = use time() + localtime() */
+ unsigned int timestamp_usecs;
+ const char *log_prefix; /* override the default log prefix */
+ /* If non-0, insert the log type text (e.g. "Info: ") at this position
+ in the log_prefix instead of appending it. */
+ unsigned int log_prefix_type_pos;
+};
+
+#define DEFAULT_FAILURE_STAMP_FORMAT "%b %d %H:%M:%S "
+
+typedef void failure_callback_t(const struct failure_context *ctx,
+ const char *format, va_list args);
+
+extern const char *failure_log_type_prefixes[];
+extern const char *failure_log_type_names[];
+
+void i_log_type(const struct failure_context *ctx, const char *format, ...)
+ ATTR_FORMAT(2, 3);
+void i_log_typev(const struct failure_context *ctx, const char *format,
+ va_list args) ATTR_FORMAT(2, 0);
+
+void i_panic(const char *format, ...) ATTR_FORMAT(1, 2) ATTR_NORETURN ATTR_COLD;
+void i_unreached(const char *source_filename, int source_linenum)
+ ATTR_NORETURN ATTR_COLD;
+#define i_unreached() \
+ i_unreached(__FILE__, __LINE__)
+void i_fatal(const char *format, ...) ATTR_FORMAT(1, 2) ATTR_NORETURN ATTR_COLD;
+void i_error(const char *format, ...) ATTR_FORMAT(1, 2) ATTR_COLD;
+void i_warning(const char *format, ...) ATTR_FORMAT(1, 2);
+void i_info(const char *format, ...) ATTR_FORMAT(1, 2);
+void i_debug(const char *format, ...) ATTR_FORMAT(1, 2);
+
+void i_fatal_status(int status, const char *format, ...)
+ ATTR_FORMAT(2, 3) ATTR_NORETURN ATTR_COLD;
+
+/* Change failure handlers. */
+#ifndef __cplusplus
+void i_set_fatal_handler(failure_callback_t *callback ATTR_NORETURN);
+#else
+/* Older g++ doesn't like attributes in parameters */
+void i_set_fatal_handler(failure_callback_t *callback);
+#endif
+void i_set_error_handler(failure_callback_t *callback);
+void i_set_info_handler(failure_callback_t *callback);
+void i_set_debug_handler(failure_callback_t *callback);
+void i_get_failure_handlers(failure_callback_t **fatal_callback_r,
+ failure_callback_t **error_callback_r,
+ failure_callback_t **info_callback_r,
+ failure_callback_t **debug_callback_r);
+
+/* Send failures to file. */
+void default_fatal_handler(const struct failure_context *ctx,
+ const char *format, va_list args)
+ ATTR_NORETURN ATTR_FORMAT(2, 0);
+void default_error_handler(const struct failure_context *ctx,
+ const char *format, va_list args)
+ ATTR_FORMAT(2, 0);
+
+/* Send failures to syslog() */
+void i_syslog_fatal_handler(const struct failure_context *ctx,
+ const char *format, va_list args)
+ ATTR_NORETURN ATTR_FORMAT(2, 0);
+void i_syslog_error_handler(const struct failure_context *ctx,
+ const char *format, va_list args)
+ ATTR_FORMAT(2, 0);
+
+/* Open syslog and set failure/info/debug handlers to use it. */
+void i_set_failure_syslog(const char *ident, int options, int facility);
+
+/* Send failures to specified log file instead of stderr. */
+void i_set_failure_file(const char *path, const char *prefix);
+
+/* Send errors to stderr using internal error protocol. */
+void i_set_failure_internal(void);
+/* Returns TRUE if the given callback handler was set via
+ i_set_failure_internal(). */
+bool i_failure_handler_is_internal(failure_callback_t *const callback);
+/* If writing to log fails, ignore it instead of existing with
+ FATAL_LOGWRITE or FATAL_LOGERROR. */
+void i_set_failure_ignore_errors(bool ignore);
+
+/* Send informational messages to specified log file. i_set_failure_*()
+ functions modify the info file too, so call this function after them. */
+void i_set_info_file(const char *path);
+
+/* Send debug-level message to the given log file. The i_set_info_file()
+ function modifies also the debug log file, so call this function after it. */
+void i_set_debug_file(const char *path);
+
+/* Set the failure prefix. */
+void i_set_failure_prefix(const char *prefix_fmt, ...) ATTR_FORMAT(1, 2);
+/* Set prefix to "". */
+void i_unset_failure_prefix(void);
+/* Returns the current failure prefix (never NULL). */
+const char *i_get_failure_prefix(void);
+/* Prefix failures with a timestamp. fmt is in strftime() format. */
+void i_set_failure_timestamp_format(const char *fmt);
+/* When logging with internal error protocol, update the process's current
+ IP address / log prefix by sending it to log process. This is mainly used to
+ improve the error message if the process crashes. */
+void i_set_failure_send_ip(const struct ip_addr *ip);
+void i_set_failure_send_prefix(const char *prefix);
+
+/* Call the callback before exit()ing. The callback may update the status. */
+void i_set_failure_exit_callback(void (*callback)(int *status));
+/* Call the exit callback and exit() */
+void failure_exit(int status) ATTR_NORETURN ATTR_COLD;
+
+/* Parse a line logged using internal failure handler */
+void i_failure_parse_line(const char *line, struct failure_line *failure);
+
+void failures_deinit(void);
+
+#endif