RunTimeLibraryLoader.cxx

Go to the documentation of this file.
00001 #include "RunTimeLibraryLoader.hxx"
00002 
00003 #include <iostream>
00004 #include <cstdlib>
00005 #include <dirent.h>
00006 #ifdef WIN32
00007 #       include <windows.h>
00008 #       undef GetClassName
00009 #else
00010 #       include <dlfcn.h>
00011 #endif
00012 
00013 #include <fstream>
00014 
00015 #include "ProcessingFactory.hxx" 
00016 
00017 
00018 void RunTimeLibraryLoader::ReLoad() 
00019 {
00020         CLAM::ProcessingFactory& factory = CLAM::ProcessingFactory::GetInstance();
00021         std::list<std::string> usedLibraries=GetUsedLibraries();
00022         std::list<std::string>::const_iterator itLibraries;
00023         // iterate on used libraries
00024         for (itLibraries=usedLibraries.begin();itLibraries!=usedLibraries.end();itLibraries++)
00025         {
00026                 CLAM::ProcessingFactory::Keys keys;
00027                 keys=factory.GetKeys("library",(*itLibraries));
00028                 CLAM::ProcessingFactory::Keys::const_iterator itKeys;
00029                 // iterate on used creators of the library
00030                 for(itKeys=keys.begin();itKeys!=keys.end();itKeys++)
00031                 {
00032                         factory.DeleteCreator(*itKeys);
00033                 }
00034                 if (needReleaseHandlerOnReload())
00035                 {
00036                         void * handle=GetLibraryHandler(*itLibraries);
00037                         ReleaseLibraryHandler(handle,(*itLibraries));
00038                 }
00039         }
00040         Load();
00041 }
00042 
00043 const std::list<std::string> RunTimeLibraryLoader::GetUsedLibraries()
00044 {
00045         CLAM::ProcessingFactory& factory = CLAM::ProcessingFactory::GetInstance();
00046         std::list<std::string> usedLibraries;
00047         CLAM::ProcessingFactory::Values librariesValues=factory.GetSetOfValues("library");
00048         CLAM::ProcessingFactory::Values::const_iterator itLibraries;
00049         for (itLibraries=librariesValues.begin();itLibraries!=librariesValues.end();itLibraries++)
00050         {
00051                 const std::string & path=getPathFromFullFileName(*itLibraries); 
00052                 if (IsOnPath(path))
00053                         usedLibraries.push_back(*itLibraries);
00054         }
00055         return usedLibraries;
00056 }
00057 
00058 bool RunTimeLibraryLoader::IsOnPath(const std::string & path) const
00059 {
00060         std::string paths = GetPaths();
00061         std::vector <std::string> environmentPaths = SplitPathVariable(paths);
00062         for (unsigned i=0; i<environmentPaths.size(); i++)
00063         {
00064                 if (environmentPaths[i]==path)
00065                         return true;    
00066         }
00067         return false;
00068 }
00069 
00070 const std::string RunTimeLibraryLoader::FileOfSymbol (void * symbolAddress)
00071 {
00072 #ifndef WIN32
00073         Dl_info info;
00074         int ok=dladdr(symbolAddress,&info);
00075         if (ok)
00076                 return info.dli_fname;
00077 #endif
00078         return "";
00079 }
00080 
00081 void RunTimeLibraryLoader::Load() const
00082 {
00083         std::string path = GetPaths();
00084         // for each path, load libraries
00085         std::vector <std::string> environmentPaths = SplitPathVariable(path);
00086         for (unsigned i=0; i<environmentPaths.size(); i++)
00087         {
00088                 LoadLibrariesFromPath(environmentPaths[i]);
00089         }
00090 }
00091 
00092 void RunTimeLibraryLoader::LoadLibrariesFromPath(const std::string & path) const
00093 {
00094         DIR* dir = opendir(path.c_str());
00095         if (!dir)
00096         {
00097                 return;
00098         }
00099         while ( struct dirent * dirEntry = readdir(dir) )
00100         {
00101                 std::string pluginFilename(dirEntry->d_name);
00102                 if(pluginFilename == "." || pluginFilename == "..")
00103                         continue;
00104                 std::string pluginFullFilename(path + std::string("/") + pluginFilename);
00105                 void * handle = FullyLoadLibrary(pluginFullFilename);
00106                 SetupLibrary( handle, pluginFullFilename );
00107 //              std::cout<<"loaded plugin: "<<pluginFullFilename<<std::endl;
00108         }
00109         closedir(dir);
00110 }
00111 
00112 
00113 void * RunTimeLibraryLoader::FullyLoadLibrary(const std::string & libraryPath)
00114 {
00115 //      std::cout << "[" << libraryType() << " Plugins] FullyLoading " << libraryPath << std::endl;
00116 #ifdef WIN32
00117 //              SetErrorMode( SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT |
00118 //                      SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX );
00119         return LoadLibrary(libraryPath.c_str());
00120 #else
00121         return dlopen( libraryPath.c_str(), RTLD_NOW);
00122 #endif
00123 }
00124 
00125 
00126 void * RunTimeLibraryLoader::LazyLoadLibrary(const std::string & libraryPath)
00127 {
00128 #ifdef WIN32
00129 //      TODO: if windows allow it, add here a lazy load
00130         return 0; 
00131 #else
00132         return dlopen( libraryPath.c_str(), RTLD_LAZY);
00133 #endif
00134 }
00135 
00136 
00137 
00138 void * RunTimeLibraryLoader::GetLibraryHandler(const std::string & libraryPath) const
00139 {
00140 #ifdef WIN32 //TODO: does windows have an equivalent method to have the handler?
00141         return 0;
00142 #else
00143         return dlopen (libraryPath.c_str(), RTLD_NOLOAD);
00144 #endif
00145 }
00146 
00147 //TODO: the name argument will be used to check on the plugins map 
00148 // returns false on success, true on fail
00149 bool RunTimeLibraryLoader::ReleaseLibraryHandler(void* handle, const std::string pluginFullFilename)
00150 {
00151         if (!handle)
00152         {
00153                 std::cout<<"Cannot release an empty handle!"<<std::endl;
00154                 return true;
00155         }
00156 #ifdef WIN32
00157         return (!FreeLibrary((HMODULE)handle));
00158 #else 
00159         return (dlclose(handle));
00160 #endif
00161 }
00162 
00163 const std::string RunTimeLibraryLoader::LibraryLoadError()
00164 {
00165 #ifdef WIN32
00166         LPVOID lpMsgBuf;
00167         FormatMessage(
00168                 FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
00169                 NULL,
00170                 GetLastError(),
00171                 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
00172                 (LPTSTR) &lpMsgBuf,
00173                 0, NULL );
00174         std::string message((char*)lpMsgBuf);
00175         LocalFree(lpMsgBuf);
00176         return message;
00177 #else
00178         return dlerror();
00179 #endif
00180 }
00181 std::vector<std::string> RunTimeLibraryLoader::SplitPathVariable(const std::string & pathVariable) const
00182 {
00183         std::string content=pathVariable;
00184         std::vector<std::string> result;
00185         while (!content.empty())
00186         {
00187                 size_t separatorPos = content.find(pathSeparator());
00188                 if (separatorPos == std::string::npos)
00189                 {
00190                         result.push_back(content);
00191                         break;
00192                 } 
00193                 result.push_back(content.substr(0, separatorPos));
00194                 content = content.substr(separatorPos+1);
00195         }
00196         return result;
00197 }
00198 
00199 const std::string RunTimeLibraryLoader::GetPaths() const
00200 {
00201         const char * envPath = getenv(pathEnvironmentVar());
00202         const char * envHome = getenv("HOME");
00203         std::string path = envPath ? envPath : "";
00204         if (envHome)
00205         {
00206                 path += std::string(path.empty()? "":pathSeparator()) + envHome + homePath();
00207         }
00208         // add standardPath to the env path string (i.e. path1:path2)
00209         for (const char ** standardPath=standardPaths(); *standardPath; standardPath++)
00210                 path += std::string(path.empty()? "":pathSeparator()) + *standardPath;
00211         return path;
00212 }
00213 
00214 
00215 const std::string RunTimeLibraryLoader::CompletePathFor(const std::string & subpathAndName) const 
00216 {
00217         std::string paths=GetPaths();
00218         std::vector <std::string> environmentPaths = SplitPathVariable(paths);
00219         for (unsigned i=0; i<environmentPaths.size(); i++)
00220         {
00221                 // get file name:
00222                 std::string fileName = subpathAndName.substr( subpathAndName.rfind("/")+1); 
00223                 // testDir= root_path + subpath:
00224                 std::string testDir = environmentPaths[i] + "/" + subpathAndName.substr(0, subpathAndName.size()-fileName.size());
00225                 // check if directory exists:
00226                 DIR* dir = opendir(testDir.c_str());
00227                 if (not dir) 
00228                         continue; // directory doesn't match, skip
00229                 closedir(dir);
00230                 // check if file exists:
00231                 std::fstream fin;
00232                 std::string completeFileName=testDir+fileName;
00233                 fin.open(completeFileName.c_str(),std::ios::in);
00234                 if (not fin.is_open()) 
00235                         continue; // file doesn't exist, skip
00236                 fin.close();
00237                 return completeFileName;
00238         }
00239         return "";
00240 }

Generated on Tue Aug 12 22:33:44 2008 for CLAM by  doxygen 1.5.5