From 61f65e4dfa95e21130573b74e4cef282bd410e91 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 5 May 2024 19:41:01 +0200 Subject: Adding upstream version 3.3a. Signed-off-by: Daniel Baumann --- log.c | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 log.c (limited to 'log.c') diff --git a/log.c b/log.c new file mode 100644 index 0000000..0e0d1d1 --- /dev/null +++ b/log.c @@ -0,0 +1,166 @@ +/* $OpenBSD$ */ + +/* + * Copyright (c) 2007 Nicholas Marriott + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER + * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include +#include +#include +#include + +#include "tmux.h" + +static FILE *log_file; +static int log_level; + +/* Log callback for libevent. */ +static void +log_event_cb(__unused int severity, const char *msg) +{ + log_debug("%s", msg); +} + +/* Increment log level. */ +void +log_add_level(void) +{ + log_level++; +} + +/* Get log level. */ +int +log_get_level(void) +{ + return (log_level); +} + +/* Open logging to file. */ +void +log_open(const char *name) +{ + char *path; + + if (log_level == 0) + return; + log_close(); + + xasprintf(&path, "tmux-%s-%ld.log", name, (long)getpid()); + log_file = fopen(path, "a"); + free(path); + if (log_file == NULL) + return; + + setvbuf(log_file, NULL, _IOLBF, 0); + event_set_log_callback(log_event_cb); +} + +/* Toggle logging. */ +void +log_toggle(const char *name) +{ + if (log_level == 0) { + log_level = 1; + log_open(name); + log_debug("log opened"); + } else { + log_debug("log closed"); + log_level = 0; + log_close(); + } +} + +/* Close logging. */ +void +log_close(void) +{ + if (log_file != NULL) + fclose(log_file); + log_file = NULL; + + event_set_log_callback(NULL); +} + +/* Write a log message. */ +static void printflike(1, 0) +log_vwrite(const char *msg, va_list ap, const char *prefix) +{ + char *s, *out; + struct timeval tv; + + if (log_file == NULL) + return; + + if (vasprintf(&s, msg, ap) == -1) + return; + if (stravis(&out, s, VIS_OCTAL|VIS_CSTYLE|VIS_TAB|VIS_NL) == -1) { + free(s); + return; + } + free(s); + + gettimeofday(&tv, NULL); + if (fprintf(log_file, "%lld.%06d %s%s\n", (long long)tv.tv_sec, + (int)tv.tv_usec, prefix, out) != -1) + fflush(log_file); + free(out); +} + +/* Log a debug message. */ +void +log_debug(const char *msg, ...) +{ + va_list ap; + + if (log_file == NULL) + return; + + va_start(ap, msg); + log_vwrite(msg, ap, ""); + va_end(ap); +} + +/* Log a critical error with error string and die. */ +__dead void +fatal(const char *msg, ...) +{ + char tmp[256]; + va_list ap; + + if (snprintf(tmp, sizeof tmp, "fatal: %s: ", strerror(errno)) < 0) + exit(1); + + va_start(ap, msg); + log_vwrite(msg, ap, tmp); + va_end(ap); + + exit(1); +} + +/* Log a critical error and die. */ +__dead void +fatalx(const char *msg, ...) +{ + va_list ap; + + va_start(ap, msg); + log_vwrite(msg, ap, "fatal: "); + va_end(ap); + + exit(1); +} -- cgit v1.2.3