OW_dlSharedLibrary.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 * Copyright (C) 2001-2004 Vintela, Inc. All rights reserved.
00003 *
00004 * Redistribution and use in source and binary forms, with or without
00005 * modification, are permitted provided that the following conditions are met:
00006 *
00007 *  - Redistributions of source code must retain the above copyright notice,
00008 *    this list of conditions and the following disclaimer.
00009 *
00010 *  - Redistributions in binary form must reproduce the above copyright notice,
00011 *    this list of conditions and the following disclaimer in the documentation
00012 *    and/or other materials provided with the distribution.
00013 *
00014 *  - Neither the name of Vintela, Inc. nor the names of its
00015 *    contributors may be used to endorse or promote products derived from this
00016 *    software without specific prior written permission.
00017 *
00018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
00019 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00021 * ARE DISCLAIMED. IN NO EVENT SHALL Vintela, Inc. OR THE CONTRIBUTORS
00022 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00023 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00024 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00025 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00026 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00027 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00028 * POSSIBILITY OF SUCH DAMAGE.
00029 *******************************************************************************/
00030 
00035 #include "OW_config.h"
00036 #if defined(OW_USE_DL)
00037 #include "OW_dlSharedLibrary.hpp"
00038 #include "OW_Format.hpp"
00039 #include "OW_Mutex.hpp"
00040 #include "OW_MutexLock.hpp"
00041 #include <dlfcn.h>
00042 
00043 #include "OW_Types.hpp"
00044 
00045 #if defined(OW_USE_FAKE_LIBS)
00046 
00047 #include "OW_FileSystem.hpp"
00048 #include "OW_File.hpp"
00049 #include "OW_Array.hpp"
00050 
00051 #define OW_FAKELIB_HEADING "FAKE"
00052 #define OW_FAKELIB_HEADING_LENGTH 4
00053 
00054 // NOTE: To make a fake library, create a text file with all functions that
00055 // should be contained, in a list like:
00056 // FAKE=true
00057 // library_function1=some_unique_global_function_name
00058 // library_function2=some_other_unique_global_function_name
00059 // library_function3=some_final_unique_global_function_name
00060 // ...
00061 //
00062 // The first entry MUST begin with FAKE, and there can be NO characters before
00063 // this entry.
00064 //
00065 // Most dynamic libraries in openwbem are expected to have a getOWVersion
00066 // function, so...
00067 extern "C" const char* getOWVersion()
00068 { 
00069    return OW_VERSION;
00070 }
00071 // Now a line should be in your fake library which says:
00072 // getOWVersion=getOWVersion
00074 #endif
00075 
00076 #include <iostream>
00077 
00078 namespace OW_NAMESPACE
00079 {
00080 
00081 // static
00082 bool dlSharedLibrary::s_call_dlclose = true;
00083 
00084 Mutex dlSharedLibrary_guard;
00085 
00086 dlSharedLibrary::dlSharedLibrary(void * libhandle, const String& libName)
00087    : SharedLibrary(), m_libhandle( libhandle ), m_libName(libName)
00088 {
00089 #if defined(OW_USE_FAKE_LIBS)
00090    // Find out if it is a fake library.
00091    m_fakeLibrary = dlSharedLibrary::isFakeLibrary(libName);
00092 
00093    if ( m_fakeLibrary )
00094    {
00095       initializeSymbolMap();
00096    }
00097 #endif /* defined(OW_USE_FAKE_LIBS) */
00098 }
00099   
00100 dlSharedLibrary::~dlSharedLibrary()
00101 {
00102 #if !defined(OW_VALGRIND_SUPPORT) // dlclose()ing shared libs make it impossible to see where memory leaks occurred with valgrind.
00103    if (s_call_dlclose)
00104    {
00105       dlclose( m_libhandle );
00106    }
00107 #endif
00108 }
00109 bool dlSharedLibrary::doGetFunctionPointer(const String& functionName,
00110       void** fp) const
00111 {
00112    MutexLock l(dlSharedLibrary_guard);
00113 #if defined(OW_USE_FAKE_LIBS)
00114    String realFunctionName = functionName;
00115    // If this is a fake library, extract convert the requested function
00116    // name into the proper function name for the main executable.
00117    if ( m_fakeLibrary )
00118    {
00119       Map<String,String>::const_iterator symIter = m_symbolMap.find(functionName);
00120       if ( symIter == m_symbolMap.end() )
00121       {
00122          return false;
00123       }
00124       realFunctionName = symIter->second;
00125    }
00126    *fp = dlsym( m_libhandle, realFunctionName.c_str() );
00127 #else
00128    *fp = dlsym( m_libhandle, functionName.c_str() );
00129 #endif /* defined(OW_USE_FAKE_LIBS) */
00130      
00131    if (!*fp)
00132    {
00133       return false;
00134    }
00135    return true;
00136 }
00137 
00138 bool dlSharedLibrary::isFakeLibrary(const String& library_path)
00139 {
00140 #if defined(OW_USE_FAKE_LIBS)
00141   if ( FileSystem::canRead(library_path) )
00142   {
00143     // Read the beginning of the file and see if it
00144     // contains the fake library heading.
00145     File libfile = FileSystem::openFile(library_path);
00146 
00147     if ( libfile )
00148     {
00149       char buffer[(OW_FAKELIB_HEADING_LENGTH) + 1];
00150       size_t num_read = libfile.read(buffer,(OW_FAKELIB_HEADING_LENGTH));
00151       if ( num_read == (OW_FAKELIB_HEADING_LENGTH) )
00152       {
00153    // Null terminate it.
00154    buffer[OW_FAKELIB_HEADING_LENGTH] = '\0';
00155    if ( String(OW_FAKELIB_HEADING) == buffer )
00156    {
00157      // Yes, it's a fake library.
00158      return true;
00159    }
00160       }
00161     }
00162   }  
00163 #endif
00164   return false;
00165 }
00166 
00167 #if defined(OW_USE_FAKE_LIBS)
00168 void dlSharedLibrary::initializeSymbolMap()
00169 {
00170    if ( ! m_fakeLibrary )
00171    {
00172       return;
00173    }
00174    // Read the contents of the file to find out what the function names
00175    // (normally available from dlsym) are mapped to functions in the main
00176    // program. 
00177    StringArray lines = FileSystem::getFileLines(m_libName);
00178 
00179    for ( StringArray::const_iterator iter = lines.begin();
00180       iter != lines.end();
00181       ++iter )
00182    {
00183       // Skip commented lines.  
00184       if ( iter->startsWith('#') )
00185       {
00186          continue;
00187       }
00188       StringArray current_line = iter->tokenize("=");
00189       // Skip invalid lines.
00190       if ( current_line.size() != 2 )
00191       {
00192          continue;
00193       }
00194       // Add the data into the map.
00195       String option = String(current_line[0]).trim();
00196       String value = String(current_line[1]).trim();
00197       m_symbolMap[option] = value;
00198    }      
00199 }
00200 #endif /* defined(OW_USE_FAKE_LIBS) */
00201 
00202 } // end namespace OW_NAMESPACE
00203 
00204 #endif
00205 

Generated on Thu Feb 9 08:47:58 2006 for openwbem by  doxygen 1.4.6