summaryrefslogtreecommitdiffstats
path: root/log.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-05 17:41:01 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-05 17:41:01 +0000
commit61f65e4dfa95e21130573b74e4cef282bd410e91 (patch)
tree800970ee68d1ce0659dfbde71e1149e6a2cacf9f /log.c
parentInitial commit. (diff)
downloadtmux-61f65e4dfa95e21130573b74e4cef282bd410e91.tar.xz
tmux-61f65e4dfa95e21130573b74e4cef282bd410e91.zip
Adding upstream version 3.3a.upstream/3.3aupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'log.c')
-rw-r--r--log.c166
1 files changed, 166 insertions, 0 deletions
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 <nicholas.marriott@gmail.com>
+ *
+ * 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 <sys/types.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#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);
+}