summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>2009-10-12 22:56:41 +0000
committerdanieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7>2009-10-12 22:56:41 +0000
commit060f4034303f798ee0a55a926c2c2a120b865df4 (patch)
treef4bec8a2bd0f2818e64f825ab694d58b5f427296
parent72da918ac57590981b2ed1c2c16edc7a39ad31e6 (diff)
DLLFactory--
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@11861 e03df62e-2008-0410-955e-edbf42e46eb7
-rw-r--r--include/dynamic.h101
-rw-r--r--include/modules.h2
-rw-r--r--src/dynamic.cpp29
-rw-r--r--src/modules.cpp53
4 files changed, 33 insertions, 152 deletions
diff --git a/include/dynamic.h b/include/dynamic.h
index fe150716e..12f6ffbc9 100644
--- a/include/dynamic.h
+++ b/include/dynamic.h
@@ -14,16 +14,17 @@
#ifndef __DLL_H
#define __DLL_H
+class Module;
+
/** The DLLManager class is able to load a module file by filename,
* and locate its init_module symbol.
*/
class CoreExport DLLManager : public classbase
{
protected:
-
- /** The last error string, or NULL
+ /** The last error string
*/
- const char *err;
+ std::string err;
public:
/** This constructor loads the module using dlopen()
@@ -33,106 +34,20 @@ class CoreExport DLLManager : public classbase
DLLManager(const char *fname);
virtual ~DLLManager();
- /** Get a symbol using dynamic linking.
- * @param v A function pointer, pointing at an init_module function
- * @param sym_name The symbol name to find, usually "init_module"
- * @return true if the symbol can be found, also the symbol will be put into v.
- */
- bool GetSymbol(void **v, const char *sym_name);
-
/** Get the last error from dlopen() or dlsym().
- * @return The last error string, or NULL if no error has occured.
*/
- const char* LastError()
+ const std::string& LastError()
{
return err;
}
- /** The module handle.
- * This is OS dependent, on POSIX platforms it is a pointer to a function
- * pointer (yes, really!) and on windows it is a library handle.
+ /** The module library handle.
*/
void *h;
-};
-
-class CoreExport LoadModuleException : public CoreException
-{
- public:
- /** This constructor can be used to specify an error message before throwing.
- */
- LoadModuleException(const std::string &message)
- : CoreException(message, "the core")
- {
- }
-
- /** This destructor solves world hunger, cancels the world debt, and causes the world to end.
- * Actually no, it does nothing. Never mind.
- * @throws Nothing!
- */
- virtual ~LoadModuleException() throw() {};
-};
-
-class CoreExport FindSymbolException : public CoreException
-{
- public:
- /** This constructor can be used to specify an error message before throwing.
- */
- FindSymbolException(const std::string &message)
- : CoreException(message, "the core")
- {
- }
-
- /** This destructor solves world hunger, cancels the world debt, and causes the world to end.
- * Actually no, it does nothing. Never mind.
- * @throws Nothing!
- */
- virtual ~FindSymbolException() throw() {};
-};
-
-class Module;
-/** This is the highest-level class of the DLLFactory system used to load InspIRCd modules and commands.
- * All the dirty mucking around with dl*() is done by DLLManager, all this does it put a pretty shell on
- * it and make it nice to use to load modules and core commands. This class is quite specialised for these
- * two uses and it may not be useful more generally -- use DLLManager directly for that.
- */
-class CoreExport DLLFactory : public DLLManager
-{
- public:
- typedef Module* (initfunctype)();
- /** Pointer to the init function.
+ /** Return a module by calling the init function
*/
- initfunctype* const init_func;
-
- /** Default constructor.
- * This constructor passes its paramerers down through DLLFactoryBase and then DLLManager
- * to load the module, then calls the factory function to retrieve a pointer to a ModuleFactory
- * class. It is then down to the core to call the ModuleFactory::CreateModule() method and
- * receive a Module* which it can insert into its module lists.
- */
- DLLFactory(const char *fname, const char *func_name)
- : DLLManager(fname), init_func(NULL)
- {
- const char* error = LastError();
-
- if(!error)
- {
- if(!GetSymbol((void **)&init_func, func_name))
- {
- throw FindSymbolException("Missing " + std::string(func_name) + "() entrypoint!");
- }
- }
- else
- {
- throw LoadModuleException(error);
- }
- }
-
- /** The destructor deletes the ModuleFactory pointer.
- */
- ~DLLFactory()
- {
- }
+ Module* callInit();
};
#endif
diff --git a/include/modules.h b/include/modules.h
index b96e6c703..16a64c497 100644
--- a/include/modules.h
+++ b/include/modules.h
@@ -360,7 +360,7 @@ class CoreExport Module : public Extensible
std::string ModuleSourceFile;
/** Reference to the dlopen() value
*/
- DLLFactory* ModuleDLLFactory;
+ DLLManager* ModuleDLLManager;
/** Default constructor.
* Creates a module class.
diff --git a/src/dynamic.cpp b/src/dynamic.cpp
index 453a80127..b993b8af5 100644
--- a/src/dynamic.cpp
+++ b/src/dynamic.cpp
@@ -21,11 +21,10 @@
DLLManager::DLLManager(const char *fname)
{
- err = NULL;
-
if (!strstr(fname,".so"))
{
err = "This doesn't look like a module file to me...";
+ h = NULL;
return;
}
@@ -33,7 +32,6 @@ DLLManager::DLLManager(const char *fname)
if (!h)
{
err = dlerror();
- return;
}
}
@@ -44,24 +42,23 @@ DLLManager::~DLLManager()
dlclose(h);
}
+union init_t {
+ void* vptr;
+ Module* (*fptr)();
+};
-
-bool DLLManager::GetSymbol(void** v, const char* sym_name)
+Module* DLLManager::callInit()
{
- /*
- * try extract a symbol from the library
- * get any error message is there is any
- */
+ if (!h)
+ return NULL;
- if (h)
+ init_t initfn;
+ initfn.vptr = dlsym(h, "init_module");
+ if (!initfn.vptr)
{
- dlerror(); // clear value
- *v = dlsym(h, sym_name);
err = dlerror();
- if (!*v || err)
- return false;
+ return NULL;
}
- /* succeeded :) */
- return true;
+ return (*initfn.fptr)();
}
diff --git a/src/modules.cpp b/src/modules.cpp
index 169a3a352..1c4f47103 100644
--- a/src/modules.cpp
+++ b/src/modules.cpp
@@ -56,7 +56,7 @@ void Event::Send()
Module::Module() { }
bool Module::cull()
{
- ServerInstance->GlobalCulls.AddItem(ModuleDLLFactory);
+ ServerInstance->GlobalCulls.AddItem(ModuleDLLManager);
return true;
}
Module::~Module() { }
@@ -372,67 +372,36 @@ bool ModuleManager::Load(const char* filename)
}
Module* newmod = NULL;
- DLLFactory* newhandle = NULL;
+ DLLManager* newhandle = new DLLManager(modfile);
try
{
- /* This will throw a CoreException if there's a problem loading
- * the module file or getting a pointer to the init_module symbol.
- */
- newhandle = new DLLFactory(modfile, "init_module");
- if (newhandle->init_func)
- newmod = newhandle->init_func();
+ newmod = newhandle->callInit();
if (newmod)
{
newmod->ModuleSourceFile = filename_str;
- newmod->ModuleDLLFactory = newhandle;
+ newmod->ModuleDLLManager = newhandle;
Version v = newmod->GetVersion();
- ServerInstance->Logs->Log("MODULE", DEFAULT,"New module introduced: %s (Module version %s)%s", filename, v.version.c_str(), (!(v.Flags & VF_VENDOR) ? " [3rd Party]" : " [Vendor]"));
+ ServerInstance->Logs->Log("MODULE", DEFAULT,"New module introduced: %s (Module version %s)%s",
+ filename, v.version.c_str(), (!(v.Flags & VF_VENDOR) ? " [3rd Party]" : " [Vendor]"));
Modules[filename_str] = newmod;
}
else
{
- delete newhandle;
- LastModuleError = "Unable to load " + filename_str + ": Probably missing init_module() entrypoint, but dlsym() didn't notice a problem";
+ LastModuleError = "Unable to load " + filename_str + ": " + newhandle->LastError();
ServerInstance->Logs->Log("MODULE", DEFAULT, LastModuleError);
+ delete newhandle;
return false;
}
}
- /** XXX: Is there anything we can do about this mess? -- Brain
- * Yeah, don't use exceptions without RAII. -- Daniel
- */
- catch (LoadModuleException& modexcept)
- {
- DetachAll(newmod);
- if (newmod)
- delete newmod;
- if (newhandle)
- delete newhandle;
- LastModuleError = "Unable to load " + filename_str + ": Error when loading: " + modexcept.GetReason();
- ServerInstance->Logs->Log("MODULE", DEFAULT, LastModuleError);
- return false;
- }
- catch (FindSymbolException& modexcept)
- {
- DetachAll(newmod);
- if (newmod)
- delete newmod;
- if (newhandle)
- delete newhandle;
- LastModuleError = "Unable to load " + filename_str + ": Error finding symbol: " + modexcept.GetReason();
- ServerInstance->Logs->Log("MODULE", DEFAULT, LastModuleError);
- return false;
- }
catch (CoreException& modexcept)
{
- DetachAll(newmod);
- if (newmod)
- delete newmod;
- if (newhandle)
- delete newhandle;
+ // failure in module constructor
+ delete newmod;
+ delete newhandle;
LastModuleError = "Unable to load " + filename_str + ": " + modexcept.GetReason();
ServerInstance->Logs->Log("MODULE", DEFAULT, LastModuleError);
return false;