Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <cstdarg>
30 : : #include <cstdio>
31 : : #include <stdio.h>
32 : : #include <stdarg.h>
33 : :
34 : : #include <rtl/logfile.h>
35 : : #include <osl/process.h>
36 : : #include <osl/time.h>
37 : : #include <osl/mutex.hxx>
38 : : #include <rtl/bootstrap.h>
39 : : #include <rtl/oustringostreaminserter.hxx>
40 : : #include <rtl/ustring.hxx>
41 : : #include <rtl/ustrbuf.hxx>
42 : : #include <rtl/alloc.h>
43 : : #include <rtl/instance.hxx>
44 : : #include <sal/log.hxx>
45 : : #include "osl/thread.h"
46 : :
47 : : #include <algorithm>
48 : :
49 : : #ifdef _MSC_VER
50 : : #define vsnprintf _vsnprintf
51 : : #endif
52 : :
53 : : using namespace osl;
54 : : using namespace std;
55 : :
56 : : using ::rtl::OUString;
57 : : using ::rtl::OUStringBuffer;
58 : :
59 : : namespace {
60 : :
61 : : static oslFileHandle g_aFile = 0;
62 : : static sal_Bool g_bHasBeenCalled = sal_False;
63 : : static const sal_Int32 g_BUFFERSIZE = 4096;
64 : : static sal_Char *g_buffer = 0;
65 : :
66 : : class LoggerGuard
67 : : {
68 : : public:
69 : : ~LoggerGuard();
70 : : };
71 : :
72 : 3013 : LoggerGuard::~LoggerGuard()
73 : : {
74 [ - + ]: 3013 : if( g_buffer )
75 : : {
76 : : sal_Int64 nWritten, nConverted =
77 [ # # ]: 0 : sprintf( g_buffer, "closing log file at %06" SAL_PRIuUINT32, osl_getGlobalTimer() );
78 [ # # ]: 0 : if( nConverted > 0 )
79 [ # # ]: 0 : osl_writeFile( g_aFile, g_buffer, nConverted, (sal_uInt64 *)&nWritten );
80 [ # # ]: 0 : osl_closeFile( g_aFile );
81 : 0 : g_aFile = 0;
82 : :
83 : 0 : rtl_freeMemory( g_buffer );
84 : 0 : g_buffer = 0;
85 : 0 : g_bHasBeenCalled = sal_False;
86 : : }
87 : 3013 : }
88 : :
89 : : // The destructor of this static LoggerGuard is "activated" by the assignment to
90 : : // g_buffer in init():
91 : 3013 : LoggerGuard loggerGuard;
92 : :
93 : : namespace
94 : : {
95 : : class theLogMutex : public rtl::Static<osl::Mutex, theLogMutex>{};
96 : : }
97 : :
98 : 247 : static Mutex & getLogMutex()
99 : : {
100 : 247 : return theLogMutex::get();
101 : : }
102 : :
103 : 0 : OUString getFileUrl( const OUString &name )
104 : : {
105 : 0 : OUString aRet;
106 [ # # ]: 0 : if ( osl_getFileURLFromSystemPath( name.pData, &aRet.pData )
107 : : != osl_File_E_None )
108 : : {
109 : : SAL_WARN(
110 : : "sal", "osl_getFileURLFromSystemPath failed for \"" << name << '"');
111 : : }
112 : :
113 : 0 : OUString aWorkingDirectory;
114 [ # # ]: 0 : osl_getProcessWorkingDir( &(aWorkingDirectory.pData) );
115 [ # # ]: 0 : osl_getAbsoluteFileURL( aWorkingDirectory.pData, aRet.pData, &(aRet.pData) );
116 : :
117 : 0 : return aRet;
118 : : }
119 : :
120 : 28852 : void init() {
121 [ + + ]: 28852 : if( !g_bHasBeenCalled )
122 : : {
123 [ + - ][ + - ]: 247 : MutexGuard guard( getLogMutex() );
124 [ + - ]: 247 : if( ! g_bHasBeenCalled )
125 : : {
126 [ + - ]: 247 : OUString name( RTL_CONSTASCII_USTRINGPARAM( "RTL_LOGFILE" ) );
127 : 247 : OUString value;
128 [ - + ]: 247 : if( rtl_bootstrap_get( name.pData, &value.pData, 0 ) )
129 : : {
130 : : // Obtain process id.
131 : 0 : oslProcessIdentifier aProcessId = 0;
132 : : oslProcessInfo info;
133 : 0 : info.Size = sizeof (oslProcessInfo);
134 [ # # ][ # # ]: 0 : if (osl_getProcessInfo (0, osl_Process_IDENTIFIER, &info) == osl_Process_E_None)
135 : 0 : aProcessId = info.Ident;
136 : :
137 : : // Construct name of log file and open the file.
138 : 0 : OUStringBuffer buf( 128 );
139 [ # # ]: 0 : buf.append( value );
140 : :
141 : : // if the filename ends with .nopid, the incoming filename is not modified
142 [ # # # # ]: 0 : if( value.getLength() < 6 /* ".nopid" */ ||
[ # # ]
143 : : rtl_ustr_ascii_compare_WithLength(
144 : 0 : value.getStr() + (value.getLength()-6) , 6 , ".nopid" ) )
145 : : {
146 [ # # ]: 0 : buf.appendAscii( "_" );
147 [ # # ]: 0 : buf.append( (sal_Int32) aProcessId );
148 [ # # ]: 0 : buf.appendAscii( ".log" );
149 : : }
150 : :
151 [ # # ][ # # ]: 0 : OUString o = getFileUrl( buf.makeStringAndClear() );
152 : : oslFileError e = osl_openFile(
153 [ # # ]: 0 : o.pData, &g_aFile, osl_File_OpenFlag_Write|osl_File_OpenFlag_Create);
154 : :
155 [ # # ]: 0 : if( osl_File_E_None == e )
156 : : {
157 : : TimeValue aCurrentTime;
158 : 0 : g_buffer = ( sal_Char * ) rtl_allocateMemory( g_BUFFERSIZE );
159 : 0 : sal_Int64 nConverted = 0;
160 [ # # ][ # # ]: 0 : if (osl_getSystemTime (&aCurrentTime))
161 : : {
162 : : nConverted = (sal_Int64 ) sprintf (
163 : : g_buffer,
164 : : "opening log file %f seconds past January 1st 1970\n"
165 : : "corresponding to %" SAL_PRIuUINT32 " ms after timer start\n",
166 : : aCurrentTime.Seconds + 1e-9 * aCurrentTime.Nanosec,
167 [ # # ]: 0 : osl_getGlobalTimer());
168 : :
169 [ # # ]: 0 : if( nConverted > 0 )
170 : : {
171 : : sal_Int64 nWritten;
172 [ # # ]: 0 : osl_writeFile( g_aFile, g_buffer, nConverted , (sal_uInt64 *)&nWritten );
173 : : }
174 : : }
175 : :
176 : 0 : nConverted = sprintf (g_buffer, "Process id is %" SAL_PRIuUINT32 "\n", aProcessId);
177 [ # # ]: 0 : if( nConverted )
178 : : {
179 : : sal_Int64 nWritten;
180 [ # # ]: 0 : osl_writeFile( g_aFile, g_buffer, nConverted, (sal_uInt64 *)&nWritten );
181 : : }
182 : : }
183 : : else
184 : : {
185 : : SAL_WARN(
186 : : "sal",
187 : : "Couldn't open logfile " << o << '(' << +e << ')');
188 : 0 : }
189 : : }
190 : 247 : g_bHasBeenCalled = sal_True;
191 [ + - ]: 247 : }
192 : : }
193 : 28852 : }
194 : :
195 : : }
196 : :
197 : 0 : extern "C" void SAL_CALL rtl_logfile_trace ( const char *pszFormat, ... )
198 : : {
199 : 0 : init();
200 [ # # ]: 0 : if( g_buffer )
201 : : {
202 : : va_list args;
203 : 0 : va_start(args, pszFormat);
204 : : {
205 : : sal_Int64 nConverted, nWritten;
206 [ # # ][ # # ]: 0 : MutexGuard guard( getLogMutex() );
207 : 0 : nConverted = vsnprintf( g_buffer , g_BUFFERSIZE, pszFormat, args );
208 : 0 : nConverted = (nConverted > g_BUFFERSIZE ? g_BUFFERSIZE : nConverted );
209 [ # # ]: 0 : if( nConverted > 0 )
210 [ # # ][ # # ]: 0 : osl_writeFile( g_aFile, g_buffer, nConverted, (sal_uInt64*)&nWritten );
211 : : }
212 : 0 : va_end(args);
213 : : }
214 : 0 : }
215 : :
216 : 28369 : extern "C" void SAL_CALL rtl_logfile_longTrace(char const * format, ...) {
217 : 28369 : init();
218 [ - + ]: 28369 : if (g_buffer != 0) {
219 [ # # ]: 0 : sal_uInt32 time = osl_getGlobalTimer();
220 [ # # ]: 0 : oslThreadIdentifier threadId = osl_getThreadIdentifier(0);
221 : : va_list args;
222 : 0 : va_start(args, format);
223 : : {
224 [ # # ][ # # ]: 0 : MutexGuard g(getLogMutex());
225 : : int n1 = snprintf(
226 : 0 : g_buffer, g_BUFFERSIZE, "%06" SAL_PRIuUINT32 " %" SAL_PRIuUINT32 " ", time, threadId);
227 [ # # ]: 0 : if (n1 >= 0) {
228 : : sal_uInt64 n2;
229 : : osl_writeFile(
230 : : g_aFile, g_buffer,
231 : : static_cast< sal_uInt64 >(
232 [ # # ]: 0 : std::min(n1, static_cast< int >(g_BUFFERSIZE))),
233 [ # # ]: 0 : &n2);
234 : 0 : n1 = vsnprintf(g_buffer, g_BUFFERSIZE, format, args);
235 [ # # ]: 0 : if (n1 > 0) {
236 : : osl_writeFile(
237 : : g_aFile, g_buffer,
238 : : static_cast< sal_uInt64 >(
239 [ # # ]: 0 : std::min(n1, static_cast< int >(g_BUFFERSIZE))),
240 [ # # ]: 0 : &n2);
241 : : }
242 [ # # ]: 0 : }
243 : : }
244 : 0 : va_end(args);
245 : : }
246 : 28369 : }
247 : :
248 : 483 : extern "C" sal_Bool SAL_CALL rtl_logfile_hasLogFile( void ) {
249 : 483 : init();
250 : 483 : return g_buffer != 0;
251 [ + - ][ + - ]: 9039 : }
252 : :
253 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|