| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_sal.hxx" |
| #include <cstdarg> |
| #include <cstdio> |
| #include <stdio.h> |
| #include <stdarg.h> |
| |
| #include <rtl/logfile.h> |
| #include <osl/process.h> |
| #ifndef _OSL_FILE_H_ |
| #include <osl/time.h> |
| #endif |
| #include <osl/time.h> |
| #include <osl/mutex.hxx> |
| #include <rtl/bootstrap.h> |
| #include <rtl/ustring.hxx> |
| #ifndef _RTL_STRBUF_HXX_ |
| #include <rtl/ustrbuf.hxx> |
| #endif |
| #include <rtl/alloc.h> |
| #include "osl/thread.h" |
| |
| #include <algorithm> |
| |
| #ifdef _MSC_VER |
| #define vsnprintf _vsnprintf |
| #endif |
| |
| using namespace rtl; |
| using namespace osl; |
| using namespace std; |
| |
| namespace { |
| |
| static oslFileHandle g_aFile = 0; |
| static sal_Bool g_bHasBeenCalled = sal_False; |
| static const sal_Int32 g_BUFFERSIZE = 4096; |
| static sal_Char *g_buffer = 0; |
| |
| class LoggerGuard |
| { |
| public: |
| ~LoggerGuard(); |
| }; |
| |
| LoggerGuard::~LoggerGuard() |
| { |
| if( g_buffer ) |
| { |
| sal_Int64 nWritten, nConverted = |
| sprintf( g_buffer, "closing log file at %06" SAL_PRIuUINT32, osl_getGlobalTimer() ); |
| if( nConverted > 0 ) |
| osl_writeFile( g_aFile, g_buffer, nConverted, (sal_uInt64 *)&nWritten ); |
| osl_closeFile( g_aFile ); |
| g_aFile = 0; |
| |
| rtl_freeMemory( g_buffer ); |
| g_buffer = 0; |
| g_bHasBeenCalled = sal_False; |
| } |
| } |
| |
| // The destructor of this static LoggerGuard is "activated" by the assignment to |
| // g_buffer in init(): |
| LoggerGuard loggerGuard; |
| |
| Mutex & getLogMutex() |
| { |
| static Mutex *pMutex = 0; |
| if( !pMutex ) |
| { |
| MutexGuard guard( Mutex::getGlobalMutex() ); |
| if( ! pMutex ) |
| { |
| static Mutex mutex; |
| pMutex = &mutex; |
| } |
| } |
| return *pMutex; |
| } |
| |
| OUString getFileUrl( const OUString &name ) |
| { |
| OUString aRet; |
| if ( osl_getFileURLFromSystemPath( name.pData, &aRet.pData ) |
| != osl_File_E_None ) |
| { |
| OSL_ASSERT( false ); |
| } |
| |
| OUString aWorkingDirectory; |
| osl_getProcessWorkingDir( &(aWorkingDirectory.pData) ); |
| osl_getAbsoluteFileURL( aWorkingDirectory.pData, aRet.pData, &(aRet.pData) ); |
| |
| return aRet; |
| } |
| |
| void init() { |
| if( !g_bHasBeenCalled ) |
| { |
| MutexGuard guard( getLogMutex() ); |
| if( ! g_bHasBeenCalled ) |
| { |
| OUString name( RTL_CONSTASCII_USTRINGPARAM( "RTL_LOGFILE" ) ); |
| OUString value; |
| if( rtl_bootstrap_get( name.pData, &value.pData, 0 ) ) |
| { |
| // Obtain process id. |
| oslProcessIdentifier aProcessId = 0; |
| oslProcessInfo info; |
| info.Size = sizeof (oslProcessInfo); |
| if (osl_getProcessInfo (0, osl_Process_IDENTIFIER, &info) == osl_Process_E_None) |
| aProcessId = info.Ident; |
| |
| // Construct name of log file and open the file. |
| OUStringBuffer buf( 128 ); |
| buf.append( value ); |
| |
| // if the filename ends with .nopid, the incoming filename is not modified |
| if( value.getLength() < 6 /* ".nopid" */ || |
| rtl_ustr_ascii_compare_WithLength( |
| value.getStr() + (value.getLength()-6) , 6 , ".nopid" ) ) |
| { |
| buf.appendAscii( "_" ); |
| buf.append( (sal_Int32) aProcessId ); |
| buf.appendAscii( ".log" ); |
| } |
| |
| OUString o = getFileUrl( buf.makeStringAndClear() ); |
| oslFileError e = osl_openFile( |
| o.pData, &g_aFile, osl_File_OpenFlag_Write|osl_File_OpenFlag_Create); |
| |
| if( osl_File_E_None == e ) |
| { |
| TimeValue aCurrentTime; |
| g_buffer = ( sal_Char * ) rtl_allocateMemory( g_BUFFERSIZE ); |
| sal_Int64 nConverted = 0; |
| if (osl_getSystemTime (&aCurrentTime)) |
| { |
| nConverted = (sal_Int64 ) sprintf ( |
| g_buffer, |
| "opening log file %f seconds past January 1st 1970\n" |
| "corresponding to %" SAL_PRIuUINT32 " ms after timer start\n", |
| aCurrentTime.Seconds + 1e-9 * aCurrentTime.Nanosec, |
| osl_getGlobalTimer()); |
| |
| if( nConverted > 0 ) |
| { |
| sal_Int64 nWritten; |
| osl_writeFile( g_aFile, g_buffer, nConverted , (sal_uInt64 *)&nWritten ); |
| } |
| } |
| |
| nConverted = sprintf (g_buffer, "Process id is %" SAL_PRIuUINT32 "\n", aProcessId); |
| if( nConverted ) |
| { |
| sal_Int64 nWritten; |
| osl_writeFile( g_aFile, g_buffer, nConverted, (sal_uInt64 *)&nWritten ); |
| } |
| } |
| else |
| { |
| OSL_TRACE( "Couldn't open logfile %s(%d)" , o.getStr(), e ); |
| } |
| } |
| g_bHasBeenCalled = sal_True; |
| } |
| } |
| } |
| |
| } |
| |
| extern "C" void SAL_CALL rtl_logfile_trace ( const char *pszFormat, ... ) |
| { |
| init(); |
| if( g_buffer ) |
| { |
| va_list args; |
| va_start(args, pszFormat); |
| { |
| sal_Int64 nConverted, nWritten; |
| MutexGuard guard( getLogMutex() ); |
| nConverted = vsnprintf( g_buffer , g_BUFFERSIZE, pszFormat, args ); |
| nConverted = (nConverted > g_BUFFERSIZE ? g_BUFFERSIZE : nConverted ); |
| if( nConverted > 0 ) |
| osl_writeFile( g_aFile, g_buffer, nConverted, (sal_uInt64*)&nWritten ); |
| } |
| va_end(args); |
| } |
| } |
| |
| extern "C" void SAL_CALL rtl_logfile_longTrace(char const * format, ...) { |
| init(); |
| if (g_buffer != 0) { |
| sal_uInt32 time = osl_getGlobalTimer(); |
| oslThreadIdentifier threadId = osl_getThreadIdentifier(0); |
| va_list args; |
| va_start(args, format); |
| { |
| MutexGuard g(getLogMutex()); |
| int n1 = snprintf( |
| g_buffer, g_BUFFERSIZE, "%06" SAL_PRIuUINT32 " %" SAL_PRIuUINT32 " ", time, threadId); |
| if (n1 >= 0) { |
| sal_uInt64 n2; |
| osl_writeFile( |
| g_aFile, g_buffer, |
| static_cast< sal_uInt64 >( |
| std::min(n1, static_cast< int >(g_BUFFERSIZE))), |
| &n2); |
| n1 = vsnprintf(g_buffer, g_BUFFERSIZE, format, args); |
| if (n1 > 0) { |
| osl_writeFile( |
| g_aFile, g_buffer, |
| static_cast< sal_uInt64 >( |
| std::min(n1, static_cast< int >(g_BUFFERSIZE))), |
| &n2); |
| } |
| } |
| } |
| va_end(args); |
| } |
| } |
| |
| extern "C" sal_Bool SAL_CALL rtl_logfile_hasLogFile( void ) { |
| init(); |
| return g_buffer != 0; |
| } |