Correct use of localtime() in Win32
[mono.git] / mono / utils / mono-log-windows.c
1 /*
2  * mono-log-windows.c: Simplistic simulation of a syslog logger for Windows
3  *
4  * This module contains the Windows syslog logger interface
5  *
6  * Author:
7  *    Neale Ferguson <neale@sinenomine.net>
8  *
9  */
10 #include <config.h>
11
12 #ifdef HAVE_UNISTD_H
13 #include <unistd.h>
14 #endif
15
16 #ifdef HOST_WIN32
17
18 #include <stdlib.h>
19 #include <stdio.h>
20 #include <ctype.h>
21 #include <string.h>
22 #include <glib.h>
23 #include <errno.h>
24 #include <time.h>
25 #include "mono-logger.h"
26
27 static FILE *logFile = NULL;
28 static void *logUserData = NULL;
29 static char *logFileName = L".//mono.log";
30
31 /**
32  * mapSyslogLevel:
33  *      
34  *      @level - GLogLevelFlags value
35  *      @returns The equivalent character identifier
36  */
37 static inline char 
38 mapLogFileLevel(GLogLevelFlags level) 
39 {
40         if (level & G_LOG_LEVEL_ERROR)
41                 return ('E');
42         if (level & G_LOG_LEVEL_CRITICAL)
43                 return ('C');
44         if (level & G_LOG_LEVEL_WARNING)
45                 return ('W');
46         if (level & G_LOG_LEVEL_MESSAGE)
47                 return ('N');
48         if (level & G_LOG_LEVEL_INFO)
49                 return ('I');
50         if (level & G_LOG_LEVEL_DEBUG)
51                 return ('D');
52         return ('I');
53 }
54
55 /**
56  * mono_log_open_logfile
57  *      
58  *      Open the logfile. If the path is not specified default to stdout. If the
59  *      open fails issue a warning and use stdout as the log file destination.
60  *
61  *      @ident - Identifier: ignored
62  *      @userData - Not used
63  */
64 void
65 mono_log_open_syslog(const char *ident, void *userData)
66 {
67         logFile = fopen(logFileName, "w");
68         if (logFile == NULL) {
69                 g_warning("opening of log file %s failed with %s",
70                           strerror(errno));
71         }
72         logUserData = userData;
73 }
74
75 /**
76  * mono_log_write_logfile
77  *      
78  *      Write data to the log file.
79  *
80  *      @domain - Identifier string
81  *      @level - Logging level flags
82  *      @format - Printf format string
83  *      @vargs - Variable argument list
84  */
85 void
86 mono_log_write_syslog(const char *domain, GLogLevelFlags level, mono_bool hdr, const char *format, va_list args)
87 {
88         time_t t;
89         struct tm *tod;
90         char logTime[80],
91               logMessage[512];
92         pid_t pid;
93         int iLog = 0;
94         size_t nLog;
95
96         if (logFile == NULL)
97                 mono_log_open_logfile(NULL, NULL);
98
99         time(&t);
100         tod = localtime(&t);
101         pid = _getpid();
102         strftime(logTime, sizeof(logTime), "%F %T", tod);
103         iLog = snprintf(logMessage, sizeof(logMessage), "%s level[%c] mono[%d]: ",
104                         logTime,mapLogFileLevel(level),pid);
105         nLog = sizeof(logMessage) - iLog - 2;
106         iLog = vsnprintf(logMessage+iLog, nLog, format, args);
107         logMessage[iLog++] = '\n';
108         logMessage[iLog++] = 0;
109         fputs(logMessage, logFile);
110         fflush(logFile);
111
112         if (level == G_LOG_FLAG_FATAL)
113                 abort();
114 }
115
116 /**
117  * mono_log_close_logfile
118  *
119  *      Close the log file
120  */
121 void
122 mono_log_close_syslog()
123 {
124         if (logFile) {
125                 fclose(logFile);
126                 logFile = NULL;
127         }
128 }
129 #endif