xref: /minix3/external/bsd/tmux/dist/log.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /* Id */
2eda6f593SDavid van Moolenbroek 
3eda6f593SDavid van Moolenbroek /*
4eda6f593SDavid van Moolenbroek  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
5eda6f593SDavid van Moolenbroek  *
6eda6f593SDavid van Moolenbroek  * Permission to use, copy, modify, and distribute this software for any
7eda6f593SDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
8eda6f593SDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
9eda6f593SDavid van Moolenbroek  *
10eda6f593SDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11eda6f593SDavid van Moolenbroek  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12eda6f593SDavid van Moolenbroek  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13eda6f593SDavid van Moolenbroek  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14eda6f593SDavid van Moolenbroek  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15eda6f593SDavid van Moolenbroek  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16eda6f593SDavid van Moolenbroek  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17eda6f593SDavid van Moolenbroek  */
18eda6f593SDavid van Moolenbroek 
19eda6f593SDavid van Moolenbroek #include <sys/types.h>
20eda6f593SDavid van Moolenbroek 
21eda6f593SDavid van Moolenbroek #include <errno.h>
22eda6f593SDavid van Moolenbroek #include <stdio.h>
23eda6f593SDavid van Moolenbroek #include <stdlib.h>
24eda6f593SDavid van Moolenbroek #include <string.h>
25eda6f593SDavid van Moolenbroek #include <syslog.h>
26eda6f593SDavid van Moolenbroek #include <time.h>
27eda6f593SDavid van Moolenbroek 
28eda6f593SDavid van Moolenbroek #include "tmux.h"
29eda6f593SDavid van Moolenbroek 
30eda6f593SDavid van Moolenbroek /* Log file, if needed. */
31eda6f593SDavid van Moolenbroek FILE		*log_file;
32eda6f593SDavid van Moolenbroek 
33eda6f593SDavid van Moolenbroek /* Debug level. */
34*0a6a1f1dSLionel Sambuc int		 log_level = 0;
35eda6f593SDavid van Moolenbroek 
36*0a6a1f1dSLionel Sambuc void		 log_event_cb(int, const char *);
37*0a6a1f1dSLionel Sambuc void		 log_vwrite(const char *, va_list) __printflike(1, 0);
38eda6f593SDavid van Moolenbroek __dead void	 log_vfatal(const char *, va_list);
39eda6f593SDavid van Moolenbroek 
40*0a6a1f1dSLionel Sambuc /* Log callback for libevent. */
41eda6f593SDavid van Moolenbroek void
log_event_cb(unused int severity,const char * msg)42*0a6a1f1dSLionel Sambuc log_event_cb(unused int severity, const char *msg)
43eda6f593SDavid van Moolenbroek {
44*0a6a1f1dSLionel Sambuc 	log_warnx("%s", msg);
45eda6f593SDavid van Moolenbroek }
46eda6f593SDavid van Moolenbroek 
47eda6f593SDavid van Moolenbroek /* Open logging to file. */
48eda6f593SDavid van Moolenbroek void
log_open(int level,const char * path)49*0a6a1f1dSLionel Sambuc log_open(int level, const char *path)
50eda6f593SDavid van Moolenbroek {
51eda6f593SDavid van Moolenbroek 	log_file = fopen(path, "w");
52eda6f593SDavid van Moolenbroek 	if (log_file == NULL)
53eda6f593SDavid van Moolenbroek 		return;
54eda6f593SDavid van Moolenbroek 	log_level = level;
55eda6f593SDavid van Moolenbroek 
56eda6f593SDavid van Moolenbroek 	setlinebuf(log_file);
57*0a6a1f1dSLionel Sambuc 	event_set_log_callback(log_event_cb);
58eda6f593SDavid van Moolenbroek 
59eda6f593SDavid van Moolenbroek 	tzset();
60eda6f593SDavid van Moolenbroek }
61eda6f593SDavid van Moolenbroek 
62eda6f593SDavid van Moolenbroek /* Close logging. */
63eda6f593SDavid van Moolenbroek void
log_close(void)64eda6f593SDavid van Moolenbroek log_close(void)
65eda6f593SDavid van Moolenbroek {
66*0a6a1f1dSLionel Sambuc 	if (log_file != NULL)
67eda6f593SDavid van Moolenbroek 		fclose(log_file);
68eda6f593SDavid van Moolenbroek 
69*0a6a1f1dSLionel Sambuc 	event_set_log_callback(NULL);
70eda6f593SDavid van Moolenbroek }
71eda6f593SDavid van Moolenbroek 
72eda6f593SDavid van Moolenbroek /* Write a log message. */
73eda6f593SDavid van Moolenbroek void
log_vwrite(const char * msg,va_list ap)74*0a6a1f1dSLionel Sambuc log_vwrite(const char *msg, va_list ap)
75eda6f593SDavid van Moolenbroek {
76*0a6a1f1dSLionel Sambuc 	if (log_file == NULL)
77*0a6a1f1dSLionel Sambuc 		return;
78eda6f593SDavid van Moolenbroek 
79*0a6a1f1dSLionel Sambuc 	if (vfprintf(log_file, msg, ap) == -1)
80eda6f593SDavid van Moolenbroek 		exit(1);
81*0a6a1f1dSLionel Sambuc 	if (fprintf(log_file, "\n") == -1)
82eda6f593SDavid van Moolenbroek 		exit(1);
83*0a6a1f1dSLionel Sambuc 	fflush(log_file);
84eda6f593SDavid van Moolenbroek }
85eda6f593SDavid van Moolenbroek 
86eda6f593SDavid van Moolenbroek /* Log a warning with error string. */
87*0a6a1f1dSLionel Sambuc #if __GNUC_PREREQ__(4, 6) || defined(__clang__)
88*0a6a1f1dSLionel Sambuc #pragma GCC diagnostic push
89*0a6a1f1dSLionel Sambuc #endif
90*0a6a1f1dSLionel Sambuc #if __GNUC_PREREQ__(4, 5) || defined(__clang__)
91*0a6a1f1dSLionel Sambuc #pragma GCC diagnostic ignored "-Wformat-nonliteral"
92*0a6a1f1dSLionel Sambuc #endif
93eda6f593SDavid van Moolenbroek void printflike1
log_warn(const char * msg,...)94eda6f593SDavid van Moolenbroek log_warn(const char *msg, ...)
95eda6f593SDavid van Moolenbroek {
96eda6f593SDavid van Moolenbroek 	va_list	 ap;
97eda6f593SDavid van Moolenbroek 	char	*fmt;
98eda6f593SDavid van Moolenbroek 
99eda6f593SDavid van Moolenbroek 	va_start(ap, msg);
100eda6f593SDavid van Moolenbroek 	if (asprintf(&fmt, "%s: %s", msg, strerror(errno)) == -1)
101eda6f593SDavid van Moolenbroek 		exit(1);
102*0a6a1f1dSLionel Sambuc 	log_vwrite(fmt, ap);
103eda6f593SDavid van Moolenbroek 	free(fmt);
104eda6f593SDavid van Moolenbroek 	va_end(ap);
105eda6f593SDavid van Moolenbroek }
106*0a6a1f1dSLionel Sambuc #if __GNUC_PREREQ__(4, 6) || defined(__clang__)
107*0a6a1f1dSLionel Sambuc #pragma GCC diagnostic push
108*0a6a1f1dSLionel Sambuc #endif
109eda6f593SDavid van Moolenbroek 
110eda6f593SDavid van Moolenbroek /* Log a warning. */
111eda6f593SDavid van Moolenbroek void printflike1
log_warnx(const char * msg,...)112eda6f593SDavid van Moolenbroek log_warnx(const char *msg, ...)
113eda6f593SDavid van Moolenbroek {
114eda6f593SDavid van Moolenbroek 	va_list	ap;
115eda6f593SDavid van Moolenbroek 
116eda6f593SDavid van Moolenbroek 	va_start(ap, msg);
117*0a6a1f1dSLionel Sambuc 	log_vwrite(msg, ap);
118eda6f593SDavid van Moolenbroek 	va_end(ap);
119eda6f593SDavid van Moolenbroek }
120eda6f593SDavid van Moolenbroek 
121eda6f593SDavid van Moolenbroek /* Log an informational message. */
122eda6f593SDavid van Moolenbroek void printflike1
log_info(const char * msg,...)123eda6f593SDavid van Moolenbroek log_info(const char *msg, ...)
124eda6f593SDavid van Moolenbroek {
125eda6f593SDavid van Moolenbroek 	va_list	ap;
126eda6f593SDavid van Moolenbroek 
127eda6f593SDavid van Moolenbroek 	if (log_level > -1) {
128eda6f593SDavid van Moolenbroek 		va_start(ap, msg);
129*0a6a1f1dSLionel Sambuc 		log_vwrite(msg, ap);
130eda6f593SDavid van Moolenbroek 		va_end(ap);
131eda6f593SDavid van Moolenbroek 	}
132eda6f593SDavid van Moolenbroek }
133eda6f593SDavid van Moolenbroek 
134eda6f593SDavid van Moolenbroek /* Log a debug message. */
135eda6f593SDavid van Moolenbroek void printflike1
log_debug(const char * msg,...)136eda6f593SDavid van Moolenbroek log_debug(const char *msg, ...)
137eda6f593SDavid van Moolenbroek {
138eda6f593SDavid van Moolenbroek 	va_list	ap;
139eda6f593SDavid van Moolenbroek 
140eda6f593SDavid van Moolenbroek 	if (log_level > 0) {
141eda6f593SDavid van Moolenbroek 		va_start(ap, msg);
142*0a6a1f1dSLionel Sambuc 		log_vwrite(msg, ap);
143eda6f593SDavid van Moolenbroek 		va_end(ap);
144eda6f593SDavid van Moolenbroek 	}
145eda6f593SDavid van Moolenbroek }
146eda6f593SDavid van Moolenbroek 
147eda6f593SDavid van Moolenbroek /* Log a debug message at level 2. */
148eda6f593SDavid van Moolenbroek void printflike1
log_debug2(const char * msg,...)149eda6f593SDavid van Moolenbroek log_debug2(const char *msg, ...)
150eda6f593SDavid van Moolenbroek {
151eda6f593SDavid van Moolenbroek 	va_list	ap;
152eda6f593SDavid van Moolenbroek 
153eda6f593SDavid van Moolenbroek 	if (log_level > 1) {
154eda6f593SDavid van Moolenbroek 		va_start(ap, msg);
155*0a6a1f1dSLionel Sambuc 		log_vwrite(msg, ap);
156eda6f593SDavid van Moolenbroek 		va_end(ap);
157eda6f593SDavid van Moolenbroek 	}
158eda6f593SDavid van Moolenbroek }
159eda6f593SDavid van Moolenbroek 
160eda6f593SDavid van Moolenbroek /* Log a critical error, with error string if necessary, and die. */
161eda6f593SDavid van Moolenbroek __dead void
log_vfatal(const char * msg,va_list ap)162eda6f593SDavid van Moolenbroek log_vfatal(const char *msg, va_list ap)
163eda6f593SDavid van Moolenbroek {
164eda6f593SDavid van Moolenbroek 	char	*fmt;
165eda6f593SDavid van Moolenbroek 
166eda6f593SDavid van Moolenbroek 	if (errno != 0) {
167eda6f593SDavid van Moolenbroek 		if (asprintf(&fmt, "fatal: %s: %s", msg, strerror(errno)) == -1)
168eda6f593SDavid van Moolenbroek 			exit(1);
169*0a6a1f1dSLionel Sambuc 		log_vwrite(fmt, ap);
170eda6f593SDavid van Moolenbroek 	} else {
171eda6f593SDavid van Moolenbroek 		if (asprintf(&fmt, "fatal: %s", msg) == -1)
172eda6f593SDavid van Moolenbroek 			exit(1);
173*0a6a1f1dSLionel Sambuc 		log_vwrite(fmt, ap);
174eda6f593SDavid van Moolenbroek 	}
175eda6f593SDavid van Moolenbroek 	free(fmt);
176eda6f593SDavid van Moolenbroek 
177eda6f593SDavid van Moolenbroek 	exit(1);
178eda6f593SDavid van Moolenbroek }
179eda6f593SDavid van Moolenbroek 
180eda6f593SDavid van Moolenbroek /* Log a critical error, with error string, and die. */
181eda6f593SDavid van Moolenbroek __dead void printflike1
log_fatal(const char * msg,...)182eda6f593SDavid van Moolenbroek log_fatal(const char *msg, ...)
183eda6f593SDavid van Moolenbroek {
184eda6f593SDavid van Moolenbroek 	va_list	ap;
185eda6f593SDavid van Moolenbroek 
186eda6f593SDavid van Moolenbroek 	va_start(ap, msg);
187eda6f593SDavid van Moolenbroek 	log_vfatal(msg, ap);
188eda6f593SDavid van Moolenbroek }
189eda6f593SDavid van Moolenbroek 
190eda6f593SDavid van Moolenbroek /* Log a critical error and die. */
191eda6f593SDavid van Moolenbroek __dead void printflike1
log_fatalx(const char * msg,...)192eda6f593SDavid van Moolenbroek log_fatalx(const char *msg, ...)
193eda6f593SDavid van Moolenbroek {
194eda6f593SDavid van Moolenbroek 	va_list	ap;
195eda6f593SDavid van Moolenbroek 
196eda6f593SDavid van Moolenbroek 	errno = 0;
197eda6f593SDavid van Moolenbroek 	va_start(ap, msg);
198eda6f593SDavid van Moolenbroek 	log_vfatal(msg, ap);
199eda6f593SDavid van Moolenbroek }
200