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