xref: /openbsd/usr.bin/tmux/log.c (revision 3e8355bd)
1 /* $OpenBSD: log.c,v 1.31 2022/05/30 12:55:25 nicm Exp $ */
2 
3 /*
4  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/types.h>
20 
21 #include <errno.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <unistd.h>
26 #include <vis.h>
27 
28 #include "tmux.h"
29 
30 static FILE	*log_file;
31 static int	 log_level;
32 
33 /* Log callback for libevent. */
34 static void
log_event_cb(__unused int severity,const char * msg)35 log_event_cb(__unused int severity, const char *msg)
36 {
37 	log_debug("%s", msg);
38 }
39 
40 /* Increment log level. */
41 void
log_add_level(void)42 log_add_level(void)
43 {
44 	log_level++;
45 }
46 
47 /* Get log level. */
48 int
log_get_level(void)49 log_get_level(void)
50 {
51 	return (log_level);
52 }
53 
54 /* Open logging to file. */
55 void
log_open(const char * name)56 log_open(const char *name)
57 {
58 	char	*path;
59 
60 	if (log_level == 0)
61 		return;
62 	log_close();
63 
64 	xasprintf(&path, "tmux-%s-%ld.log", name, (long)getpid());
65 	log_file = fopen(path, "a");
66 	free(path);
67 	if (log_file == NULL)
68 		return;
69 
70 	setvbuf(log_file, NULL, _IOLBF, 0);
71 	event_set_log_callback(log_event_cb);
72 }
73 
74 /* Toggle logging. */
75 void
log_toggle(const char * name)76 log_toggle(const char *name)
77 {
78 	if (log_level == 0) {
79 		log_level = 1;
80 		log_open(name);
81 		log_debug("log opened");
82 	} else {
83 		log_debug("log closed");
84 		log_level = 0;
85 		log_close();
86 	}
87 }
88 
89 /* Close logging. */
90 void
log_close(void)91 log_close(void)
92 {
93 	if (log_file != NULL)
94 		fclose(log_file);
95 	log_file = NULL;
96 
97 	event_set_log_callback(NULL);
98 }
99 
100 /* Write a log message. */
101 static void printflike(1, 0)
log_vwrite(const char * msg,va_list ap,const char * prefix)102 log_vwrite(const char *msg, va_list ap, const char *prefix)
103 {
104 	char		*s, *out;
105 	struct timeval	 tv;
106 
107 	if (log_file == NULL)
108 		return;
109 
110 	if (vasprintf(&s, msg, ap) == -1)
111 		return;
112 	if (stravis(&out, s, VIS_OCTAL|VIS_CSTYLE|VIS_TAB|VIS_NL) == -1) {
113 		free(s);
114 		return;
115 	}
116 	free(s);
117 
118 	gettimeofday(&tv, NULL);
119 	if (fprintf(log_file, "%lld.%06d %s%s\n", (long long)tv.tv_sec,
120 	    (int)tv.tv_usec, prefix, out) != -1)
121 		fflush(log_file);
122 	free(out);
123 }
124 
125 /* Log a debug message. */
126 void
log_debug(const char * msg,...)127 log_debug(const char *msg, ...)
128 {
129 	va_list	ap;
130 
131 	if (log_file == NULL)
132 		return;
133 
134 	va_start(ap, msg);
135 	log_vwrite(msg, ap, "");
136 	va_end(ap);
137 }
138 
139 /* Log a critical error with error string and die. */
140 __dead void
fatal(const char * msg,...)141 fatal(const char *msg, ...)
142 {
143 	char	 tmp[256];
144 	va_list	 ap;
145 
146 	if (snprintf(tmp, sizeof tmp, "fatal: %s: ", strerror(errno)) < 0)
147 		exit(1);
148 
149 	va_start(ap, msg);
150 	log_vwrite(msg, ap, tmp);
151 	va_end(ap);
152 
153 	exit(1);
154 }
155 
156 /* Log a critical error and die. */
157 __dead void
fatalx(const char * msg,...)158 fatalx(const char *msg, ...)
159 {
160 	va_list	 ap;
161 
162 	va_start(ap, msg);
163 	log_vwrite(msg, ap, "fatal: ");
164 	va_end(ap);
165 
166 	exit(1);
167 }
168