Annotation of src/usr.bin/tmux/log.c, Revision 1.5
1.5 ! nicm 1: /* $OpenBSD: log.c,v 1.4 2009/12/03 22:50:10 nicm Exp $ */
1.1 nicm 2:
3: /*
4: * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
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 <syslog.h>
26: #include <time.h>
27:
28: #include "tmux.h"
29:
30: /* Logging type. */
31: #define LOG_TYPE_OFF 0
1.2 nicm 32: #define LOG_TYPE_TTY 1
33: #define LOG_TYPE_FILE 2
1.1 nicm 34: int log_type = LOG_TYPE_OFF;
35:
36: /* Log file, if needed. */
37: FILE *log_file;
38:
39: /* Debug level. */
40: int log_level;
41:
1.2 nicm 42: void log_vwrite(int, const char *, va_list);
43: __dead void log_vfatal(const char *, va_list);
1.1 nicm 44:
1.5 ! nicm 45: /* Log callback for libevent. */
! 46: void
! 47: log_event_cb(unused int severity, const char *msg)
! 48: {
! 49: log_warnx(msg);
! 50: }
! 51:
1.1 nicm 52: /* Open logging to tty. */
53: void
54: log_open_tty(int level)
55: {
56: log_type = LOG_TYPE_TTY;
57: log_level = level;
58:
59: setlinebuf(stderr);
60: setlinebuf(stdout);
1.5 ! nicm 61: event_set_log_callback(log_event_cb);
1.1 nicm 62:
63: tzset();
64: }
65:
66: /* Open logging to file. */
67: void
68: log_open_file(int level, const char *path)
69: {
70: log_file = fopen(path, "w");
71: if (log_file == NULL)
72: return;
73:
74: log_type = LOG_TYPE_FILE;
75: log_level = level;
76:
77: setlinebuf(log_file);
1.5 ! nicm 78: event_set_log_callback(log_event_cb);
1.1 nicm 79:
80: tzset();
81: }
82:
83: /* Close logging. */
84: void
85: log_close(void)
86: {
87: if (log_type == LOG_TYPE_FILE)
88: fclose(log_file);
1.5 ! nicm 89:
! 90: event_set_log_callback(NULL);
1.1 nicm 91:
92: log_type = LOG_TYPE_OFF;
93: }
94:
95: /* Write a log message. */
96: void
97: log_vwrite(int pri, const char *msg, va_list ap)
98: {
99: char *fmt;
100: FILE *f = log_file;
101:
102: switch (log_type) {
103: case LOG_TYPE_TTY:
104: if (pri == LOG_INFO)
105: f = stdout;
106: else
107: f = stderr;
108: /* FALLTHROUGH */
109: case LOG_TYPE_FILE:
110: if (asprintf(&fmt, "%s\n", msg) == -1)
111: exit(1);
112: if (vfprintf(f, fmt, ap) == -1)
113: exit(1);
114: fflush(f);
115: free(fmt);
116: break;
117: }
118: }
119:
120: /* Log a warning with error string. */
121: void printflike1
122: log_warn(const char *msg, ...)
123: {
124: va_list ap;
125: char *fmt;
126:
127: va_start(ap, msg);
128: if (asprintf(&fmt, "%s: %s", msg, strerror(errno)) == -1)
129: exit(1);
130: log_vwrite(LOG_CRIT, fmt, ap);
131: free(fmt);
132: va_end(ap);
133: }
134:
135: /* Log a warning. */
136: void printflike1
137: log_warnx(const char *msg, ...)
138: {
139: va_list ap;
140:
141: va_start(ap, msg);
142: log_vwrite(LOG_CRIT, msg, ap);
143: va_end(ap);
144: }
145:
146: /* Log an informational message. */
147: void printflike1
148: log_info(const char *msg, ...)
149: {
150: va_list ap;
151:
152: if (log_level > -1) {
153: va_start(ap, msg);
154: log_vwrite(LOG_INFO, msg, ap);
155: va_end(ap);
156: }
157: }
158:
159: /* Log a debug message. */
160: void printflike1
161: log_debug(const char *msg, ...)
162: {
163: va_list ap;
164:
165: if (log_level > 0) {
166: va_start(ap, msg);
167: log_vwrite(LOG_DEBUG, msg, ap);
168: va_end(ap);
169: }
170: }
171:
172: /* Log a debug message at level 2. */
173: void printflike1
174: log_debug2(const char *msg, ...)
175: {
176: va_list ap;
177:
178: if (log_level > 1) {
179: va_start(ap, msg);
180: log_vwrite(LOG_DEBUG, msg, ap);
181: va_end(ap);
182: }
183: }
184:
185: /* Log a critical error, with error string if necessary, and die. */
186: __dead void
187: log_vfatal(const char *msg, va_list ap)
188: {
189: char *fmt;
190:
191: if (errno != 0) {
192: if (asprintf(&fmt, "fatal: %s: %s", msg, strerror(errno)) == -1)
193: exit(1);
194: log_vwrite(LOG_CRIT, fmt, ap);
195: } else {
196: if (asprintf(&fmt, "fatal: %s", msg) == -1)
1.4 nicm 197: exit(1);
1.1 nicm 198: log_vwrite(LOG_CRIT, fmt, ap);
199: }
200: free(fmt);
201:
202: exit(1);
203: }
204:
205: /* Log a critical error, with error string, and die. */
206: __dead void printflike1
207: log_fatal(const char *msg, ...)
208: {
209: va_list ap;
210:
211: va_start(ap, msg);
212: log_vfatal(msg, ap);
213: }
214:
215: /* Log a critical error and die. */
216: __dead void printflike1
217: log_fatalx(const char *msg, ...)
218: {
219: va_list ap;
220:
221: errno = 0;
222: va_start(ap, msg);
223: log_vfatal(msg, ap);
224: }