[test-runner] Write stdout/stderr into StringBuilder instead of an intermediate file
[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 <process.h>
26 #include "mono-logger.h"
27
28 static FILE *logFile = NULL;
29 static void *logUserData = NULL;
30 static wchar_t *logFileName = L".//mono.log";
31
32 /**
33  * mapSyslogLevel:
34  *      
35  *      @level - GLogLevelFlags value
36  *      @returns The equivalent character identifier
37  */
38 static inline char 
39 mapLogFileLevel(GLogLevelFlags level) 
40 {
41         if (level & G_LOG_LEVEL_ERROR)
42                 return ('E');
43         if (level & G_LOG_LEVEL_CRITICAL)
44                 return ('C');
45         if (level & G_LOG_LEVEL_WARNING)
46                 return ('W');
47         if (level & G_LOG_LEVEL_MESSAGE)
48                 return ('N');
49         if (level & G_LOG_LEVEL_INFO)
50                 return ('I');
51         if (level & G_LOG_LEVEL_DEBUG)
52                 return ('D');
53         return ('I');
54 }
55
56 /**
57  * mono_log_open_syslog
58  *      
59  *      Open the syslog file. If the open fails issue a warning and 
60  *      use stdout as the log file destination.
61  *
62  *      @ident - Identifier: ignored
63  *      @userData - Not used
64  */
65 void
66 mono_log_open_syslog(const char *ident, void *userData)
67 {
68         logFile = _wfopen(logFileName, L"w");
69         if (logFile == NULL) {
70                 g_warning("opening of log file %s failed with %s",
71                           strerror(errno));
72                 logFile = stdout;
73         }
74         logUserData = userData;
75 }
76
77 /**
78  * mono_log_write_syslog
79  *      
80  *      Write data to the syslog file.
81  *
82  *      @domain - Identifier string
83  *      @level - Logging level flags
84  *      @format - Printf format string
85  *      @vargs - Variable argument list
86  */
87 void
88 mono_log_write_syslog(const char *domain, GLogLevelFlags level, mono_bool hdr, const char *format, va_list args)
89 {
90         time_t t;
91         struct tm *tod;
92         char logTime[80],
93               logMessage[512];
94         pid_t pid;
95         int iLog = 0;
96         size_t nLog;
97
98         if (logFile == NULL)
99                 mono_log_open_syslog(NULL, NULL);
100
101         time(&t);
102         tod = localtime(&t);
103         pid = _getpid();
104         strftime(logTime, sizeof(logTime), "%Y-%m-%d %H:%M:%S", tod);
105         iLog = snprintf(logMessage, sizeof(logMessage), "%s level[%c] mono[%d]: ",
106                         logTime,mapLogFileLevel(level),pid);
107         nLog = sizeof(logMessage) - iLog - 2;
108         iLog = vsnprintf(logMessage+iLog, nLog, format, args);
109         logMessage[iLog++] = '\n';
110         logMessage[iLog++] = 0;
111         fputs(logMessage, logFile);
112         fflush(logFile);
113
114         if (level == G_LOG_FLAG_FATAL)
115                 abort();
116 }
117
118 /**
119  * mono_log_close_syslog
120  *
121  *      Close the syslog file
122  */
123 void
124 mono_log_close_syslog()
125 {
126         if (logFile) {
127                 fclose(logFile);
128                 logFile = NULL;
129         }
130 }
131 #endif