Make cmdq->client_exit a tristate (-1 means "not set") so that if
[tmux-openbsd.git] / log.c
blob2f1400cb938b4327740bc8c84c9e8aebde5be748
1 /* $OpenBSD$ */
3 /*
4 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
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.
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.
19 #include <sys/types.h>
21 #include <errno.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <syslog.h>
26 #include <time.h>
28 #include "tmux.h"
30 /* Log file, if needed. */
31 FILE *log_file;
33 /* Debug level. */
34 int log_level = 0;
36 void log_event_cb(int, const char *);
37 void log_vwrite(const char *, va_list);
38 __dead void log_vfatal(const char *, va_list);
40 /* Log callback for libevent. */
41 void
42 log_event_cb(unused int severity, const char *msg)
44 log_warnx("%s", msg);
47 /* Open logging to file. */
48 void
49 log_open(int level, const char *path)
51 log_file = fopen(path, "w");
52 if (log_file == NULL)
53 return;
54 log_level = level;
56 setlinebuf(log_file);
57 event_set_log_callback(log_event_cb);
59 tzset();
62 /* Close logging. */
63 void
64 log_close(void)
66 if (log_file != NULL)
67 fclose(log_file);
69 event_set_log_callback(NULL);
72 /* Write a log message. */
73 void
74 log_vwrite(const char *msg, va_list ap)
76 char *fmt;
78 if (log_file == NULL)
79 return;
81 if (asprintf(&fmt, "%s\n", msg) == -1)
82 exit(1);
83 if (vfprintf(log_file, fmt, ap) == -1)
84 exit(1);
85 fflush(log_file);
86 free(fmt);
89 /* Log a warning with error string. */
90 void printflike1
91 log_warn(const char *msg, ...)
93 va_list ap;
94 char *fmt;
96 va_start(ap, msg);
97 if (asprintf(&fmt, "%s: %s", msg, strerror(errno)) == -1)
98 exit(1);
99 log_vwrite(fmt, ap);
100 free(fmt);
101 va_end(ap);
104 /* Log a warning. */
105 void printflike1
106 log_warnx(const char *msg, ...)
108 va_list ap;
110 va_start(ap, msg);
111 log_vwrite(msg, ap);
112 va_end(ap);
115 /* Log an informational message. */
116 void printflike1
117 log_info(const char *msg, ...)
119 va_list ap;
121 if (log_level > -1) {
122 va_start(ap, msg);
123 log_vwrite(msg, ap);
124 va_end(ap);
128 /* Log a debug message. */
129 void printflike1
130 log_debug(const char *msg, ...)
132 va_list ap;
134 if (log_level > 0) {
135 va_start(ap, msg);
136 log_vwrite(msg, ap);
137 va_end(ap);
141 /* Log a debug message at level 2. */
142 void printflike1
143 log_debug2(const char *msg, ...)
145 va_list ap;
147 if (log_level > 1) {
148 va_start(ap, msg);
149 log_vwrite(msg, ap);
150 va_end(ap);
154 /* Log a critical error, with error string if necessary, and die. */
155 __dead void
156 log_vfatal(const char *msg, va_list ap)
158 char *fmt;
160 if (errno != 0) {
161 if (asprintf(&fmt, "fatal: %s: %s", msg, strerror(errno)) == -1)
162 exit(1);
163 log_vwrite(fmt, ap);
164 } else {
165 if (asprintf(&fmt, "fatal: %s", msg) == -1)
166 exit(1);
167 log_vwrite(fmt, ap);
169 free(fmt);
171 exit(1);
174 /* Log a critical error, with error string, and die. */
175 __dead void printflike1
176 log_fatal(const char *msg, ...)
178 va_list ap;
180 va_start(ap, msg);
181 log_vfatal(msg, ap);
184 /* Log a critical error and die. */
185 __dead void printflike1
186 log_fatalx(const char *msg, ...)
188 va_list ap;
190 errno = 0;
191 va_start(ap, msg);
192 log_vfatal(msg, ap);