diff options
Diffstat (limited to 'src/lib/failures.h')
-rw-r--r-- | src/lib/failures.h | 157 |
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 |