/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2008 by Sun Microsystems, Inc. * * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: logfile.cxx,v $ * $Revision: 1.13 $ * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sal.hxx" #include #include #include #include #include #include #ifndef _OSL_FILE_H_ #include #endif #include #include #include #include #ifndef _RTL_STRBUF_HXX_ #include #endif #include #include "osl/thread.h" #include #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; }