1 /*
2  * Copyright © 2012 Martin Minarik
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sublicense, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * The above copyright notice and this permission notice (including the
13  * next paragraph) shall be included in all copies or substantial
14  * portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19  * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
20  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
21  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23  * SOFTWARE.
24  */
25 
26 #include "config.h"
27 
28 #include <stdio.h>
29 #include <stdarg.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <sys/time.h>
33 #include <time.h>
34 
35 #include <wayland-util.h>
36 
37 #include "compositor.h"
38 
39 #include "os-compatibility.h"
40 
41 static FILE *weston_logfile = NULL;
42 
43 static int cached_tm_mday = -1;
44 
weston_log_timestamp(void)45 static int weston_log_timestamp(void)
46 {
47 	struct timeval tv;
48 	struct tm *brokendown_time;
49 	char string[128];
50 
51 	gettimeofday(&tv, NULL);
52 
53 	brokendown_time = localtime(&tv.tv_sec);
54 	if (brokendown_time == NULL)
55 		return fprintf(weston_logfile, "[(NULL)localtime] ");
56 
57 	if (brokendown_time->tm_mday != cached_tm_mday) {
58 		strftime(string, sizeof string, "%Y-%m-%d %Z", brokendown_time);
59 		fprintf(weston_logfile, "Date: %s\n", string);
60 
61 		cached_tm_mday = brokendown_time->tm_mday;
62 	}
63 
64 	strftime(string, sizeof string, "%H:%M:%S", brokendown_time);
65 
66 	return fprintf(weston_logfile, "[%s.%03li] ", string, tv.tv_usec/1000);
67 }
68 
69 static void
custom_handler(const char * fmt,va_list arg)70 custom_handler(const char *fmt, va_list arg)
71 {
72 	weston_log_timestamp();
73 	fprintf(weston_logfile, "libwayland: ");
74 	vfprintf(weston_logfile, fmt, arg);
75 }
76 
77 void
weston_log_file_open(const char * filename)78 weston_log_file_open(const char *filename)
79 {
80 	wl_log_set_handler_server(custom_handler);
81 
82 	if (filename != NULL) {
83 		weston_logfile = fopen(filename, "a");
84 		if (weston_logfile)
85 			os_fd_set_cloexec(fileno(weston_logfile));
86 	}
87 
88 	if (weston_logfile == NULL)
89 		weston_logfile = stderr;
90 	else
91 		setvbuf(weston_logfile, NULL, _IOLBF, 256);
92 }
93 
94 void
weston_log_file_close()95 weston_log_file_close()
96 {
97 	if ((weston_logfile != stderr) && (weston_logfile != NULL))
98 		fclose(weston_logfile);
99 	weston_logfile = stderr;
100 }
101 
102 WL_EXPORT int
weston_vlog(const char * fmt,va_list ap)103 weston_vlog(const char *fmt, va_list ap)
104 {
105 	int l;
106 
107 	l = weston_log_timestamp();
108 	l += vfprintf(weston_logfile, fmt, ap);
109 
110 	return l;
111 }
112 
113 WL_EXPORT int
weston_log(const char * fmt,...)114 weston_log(const char *fmt, ...)
115 {
116 	int l;
117 	va_list argp;
118 
119 	va_start(argp, fmt);
120 	l = weston_vlog(fmt, argp);
121 	va_end(argp);
122 
123 	return l;
124 }
125 
126 WL_EXPORT int
weston_vlog_continue(const char * fmt,va_list argp)127 weston_vlog_continue(const char *fmt, va_list argp)
128 {
129 	return vfprintf(weston_logfile, fmt, argp);
130 }
131 
132 WL_EXPORT int
weston_log_continue(const char * fmt,...)133 weston_log_continue(const char *fmt, ...)
134 {
135 	int l;
136 	va_list argp;
137 
138 	va_start(argp, fmt);
139 	l = weston_vlog_continue(fmt, argp);
140 	va_end(argp);
141 
142 	return l;
143 }
144