// Copyright (c) 2004 David Muse
// See the COPYING file for more information
#include <rudiments/dynamiclib.h>
#include <rudiments/charstring.h>
#include <rudiments/error.h>
#include <dlfcn.h>
#include <stdlib.h>
#ifdef RUDIMENTS_NAMESPACE
namespace rudiments {
#endif
class dynamiclibprivate {
friend class dynamiclib;
private:
void *_handle;
};
// LAME: not in the class
static mutex *_errormutex=NULL;
dynamiclib::dynamiclib() {
pvt=new dynamiclibprivate;
pvt->_handle=NULL;
}
dynamiclib::~dynamiclib() {
close();
delete pvt;
}
bool dynamiclib::open(const char *library, bool loaddependencies, bool global) {
int flag=(loaddependencies)?RTLD_NOW:RTLD_LAZY;
if (global) {
flag|=RTLD_GLOBAL;
}
do {
pvt->_handle=dlopen(library,flag);
} while (!pvt->_handle && error::getErrorNumber()==EINTR);
return (pvt->_handle!=NULL);
}
bool dynamiclib::close() {
int result;
do {
result=!dlclose(pvt->_handle);
} while (result==-1 && error::getErrorNumber()==EINTR);
return !result;
}
void *dynamiclib::getSymbol(const char *symbol) const {
void *symhandle;
do {
symhandle=dlsym(pvt->_handle,symbol);
} while (!symhandle && error::getErrorNumber()==EINTR);
return (pvt->_handle)?symhandle:NULL;
}
char *dynamiclib::getError() const {
if (_errormutex && !_errormutex->lock()) {
return NULL;
}
const char *err;
do {
err=dlerror();
} while (!err && error::getErrorNumber()==EINTR);
char *retval=NULL;
if (err) {
retval=charstring::duplicate(err);
}
if (_errormutex) {
_errormutex->unlock();
}
return retval;
}
void dynamiclib::setErrorMutex(mutex *mtx) {
_errormutex=mtx;
}
#ifdef RUDIMENTS_NAMESPACE
}
#endif
syntax highlighted by Code2HTML, v. 0.9.1