// This may look like C code, but it is really -*- C++ -*- // Gestionnaire de lien dynamique - R. Ansari 12/98 // LAL (Orsay) / IN2P3-CNRS DAPNIA/SPP (Saclay) / CEA #include #include #include #include "pdlmgr.h" // Extension de noms de fichiers Shared libs static const char* sofext = ".so"; static const char* sofext_HPUX = ".sl"; // Variables et methodes static int PDynLinkMgr::numSO = 0; string* PDynLinkMgr::tmpDir = NULL; /* --Methode-Static-- */ void PDynLinkMgr::SetTmpDir(string const & path) { if ( (path.length() > 0) && (path[path.length()] != '/') ) GetTmpDir() = path + '/'; else GetTmpDir() = path; return; } /* --Methode-Static-- */ string& PDynLinkMgr::GetTmpDir() { if (tmpDir == NULL) { tmpDir = new string(""); char* varenv; if ( (varenv=getenv("PEIDA_TMP")) != NULL ) *tmpDir = varenv; else if ( (varenv=getenv("TMPDIR")) != NULL ) *tmpDir = varenv; } return(*tmpDir); } /* --Methode-Static-- */ PDynLinkMgr* PDynLinkMgr::BuildFromCFile(string const & fname) { size_t l = fname.length(); if (l < 1) return(NULL); string fnameobj = GetTmpDir()+"tmp_pdl.o"; string cmd; int rc; // Compilation du fichier #if defined(OSF1) || defined(Linux) cmd = "cc -c -o " + fnameobj + " " + fname; #endif rc = system(cmd.c_str()); if (rc != 0) { cerr << "PDynLinkMgr::BuildFromCFile() Error Rc(" << cmd <<")= "<< rc << endl; return(NULL); } char buff[32]; numSO++; #ifndef HPUX sprintf(buff,"pdlmgr%d%s", numSO,sofext); #endif string fnameso = GetTmpDir()+buff; // Creation du shared-lib #if defined(OSF1) cmd = "ld -shared -o " + fnameso + " -all " + fnameobj + " -none -lm -lc"; #else cmd = "ld -shared -o " + fnameso + " " + fnameobj + " -lm -lc"; #endif rc = system(cmd.c_str()); if (rc != 0) { cerr << "PDynLinkMgr::BuildFromCFile() Error Rc(" << cmd <<")= "<< rc << endl; return(NULL); } PDynLinkMgr* rdyn = new PDynLinkMgr(fnameso, false); rdyn->copy = true; return(rdyn); } /* --Methode-- */ PDynLinkMgr::PDynLinkMgr(string& soname, bool cp) { dlhandle = NULL; soName = ""; if (soname.find_last_of(".") > soname.length()) #ifdef HPUX soname += sofext_HPUX; #else soname += sofext; #endif string fnameso; if (cp) { numSO++; char buff[32]; #ifndef HPUX sprintf(buff,"pdlmgr%d%s", numSO,sofext); #else sprintf(buff,"pdlmgr%d%s", numSO,sofext_HPUX); #endif fnameso = GetTmpDir()+buff; string cmd = "cp " + soname + " " + fnameso; int rc = system(cmd.c_str()); if (rc != 0) { cerr << "PDynLinkMgr::PDynLinkMgr() Error Rc(" << cmd <<")= "<< rc << endl; return; } } else fnameso = soname; copy = cp; soName = fnameso; #if defined(OSF1) || defined(Linux) dlhandle = dlopen(fnameso.c_str(), RTLD_NOW); if (dlhandle == NULL) { cerr << "PDynLinkMgr::PDynLinkMgr(): Error opening SO " << fnameso << " (" << soname << ")" << endl; string sn = dlerror(); cerr << "Loader Error (dlerror()) :" << sn << endl; return; } #endif } /* --Methode-- */ PDynLinkMgr::~PDynLinkMgr() { #if defined(OSF1) || defined(Linux) if (dlhandle) dlclose(dlhandle); dlhandle = NULL; #endif if (copy) { string cmd = "rm -f " + soName; system(cmd.c_str()); } } /* --Methode-- */ DlFunction PDynLinkMgr::GetFunction(string const & funcname) { DlFunction f = NULL; #if defined(OSF1) || defined(Linux) if (dlhandle != NULL) f = (DlFunction)dlsym(dlhandle, funcname.c_str()); #endif if (f == NULL) cerr << "PDynLinkMgr::PDynLinkMgr(): Error linking " << funcname << endl; return(f); }