Correct use of Windows APIs
[mono.git] / mono / utils / mono-log-common.c
1 /*
2  * mono-log-common.c: Platform-independent interface to the logger
3  *
4  * This module contains the POSIX 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 #include <stdlib.h>
17 #include <stdio.h>
18 #include <ctype.h>
19 #include <string.h>
20 #include <glib.h>
21 #include <errno.h>
22 #include <time.h>
23 #ifndef HOST_WIN32
24 #include <sys/time.h>
25 #endif
26 #include "mono-logger.h"
27
28 static FILE *logFile = NULL;
29 static void *logUserData = NULL;
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  *      @path - Path for log file
62  *      @userData - Not used
63  */
64 void
65 mono_log_open_logfile(const char *path, void *userData)
66 {
67         if (path == NULL) {
68                 logFile = stdout;
69         } else {
70                 logFile = fopen(path, "w");
71                 if (logFile == NULL) {
72                         g_warning("opening of log file %s failed with %s - defaulting to stdout", 
73                                   path, strerror(errno));
74                 }
75         }
76         logUserData = userData;
77 }
78
79 /**
80  * mono_log_write_logfile
81  *      
82  *      Write data to the log file.
83  *
84  *      @domain - Identifier string
85  *      @level - Logging level flags
86  *      @format - Printf format string
87  *      @vargs - Variable argument list
88  */
89 void
90 mono_log_write_logfile(const char *domain, GLogLevelFlags level, mono_bool hdr, const char *format, va_list args)
91 {
92         time_t t;
93         struct tm tod;
94         char logTime[80],       
95              logMessage[512];
96         pid_t pid;
97         int iLog = 0;
98         size_t nLog;
99
100         if (logFile == NULL)
101                 logFile = stdout;
102
103         if (hdr) {
104                 time(&t);
105 #ifndef HOST_WIN32
106                 localtime_r(&t, &tod);
107                 pid = getpid();
108 #else
109                 localtime(&t, &tod);
110                 pid = _getpid();
111 #endif
112                 strftime(logTime, sizeof(logTime), "%F %T", &tod);
113                 iLog = snprintf(logMessage, sizeof(logMessage), "%s level[%c] mono[%d]: ",
114                                 logTime,mapLogFileLevel(level),pid);
115         }
116         nLog = sizeof(logMessage) - iLog - 2;
117         iLog = vsnprintf(logMessage+iLog, nLog, format, args);
118         logMessage[iLog++] = '\n';
119         logMessage[iLog++] = '\0';
120         fputs(logMessage, logFile);
121         fflush(logFile);
122
123         if (level == G_LOG_FLAG_FATAL)
124                 abort();
125 }
126
127 /**
128  * mono_log_close_logfile
129  *
130  *      Close the log file
131  */
132 void
133 mono_log_close_logfile()
134 {
135         if (logFile) {
136                 if (logFile != stdout)
137                         fclose(logFile);
138                 logFile = NULL;
139         }
140 }