mirror of
https://github.com/matrix-construct/construct
synced 2024-11-18 07:50:57 +01:00
modules: use libltdl to load the modules
This commit is contained in:
parent
bc38c72ced
commit
f272e7abc7
2 changed files with 19 additions and 167 deletions
|
@ -32,12 +32,7 @@
|
||||||
|
|
||||||
#define MAPI_RATBOX 1
|
#define MAPI_RATBOX 1
|
||||||
|
|
||||||
#if defined(HAVE_SHL_LOAD)
|
#include <ltdl.h>
|
||||||
#include <dl.h>
|
|
||||||
#endif
|
|
||||||
#if !defined(STATIC_MODULES) && defined(HAVE_DLFCN_H)
|
|
||||||
#include <dlfcn.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "msg.h"
|
#include "msg.h"
|
||||||
#include "hook.h"
|
#include "hook.h"
|
||||||
|
@ -46,7 +41,7 @@ struct module
|
||||||
{
|
{
|
||||||
char *name;
|
char *name;
|
||||||
const char *version;
|
const char *version;
|
||||||
void *address;
|
lt_dlhandle address;
|
||||||
int core;
|
int core;
|
||||||
int mapi_version;
|
int mapi_version;
|
||||||
void * mapi_header; /* actually struct mapi_mheader_av<mapi_version> */
|
void * mapi_header; /* actually struct mapi_mheader_av<mapi_version> */
|
||||||
|
|
177
src/modules.c
177
src/modules.c
|
@ -42,6 +42,8 @@
|
||||||
|
|
||||||
#ifndef STATIC_MODULES
|
#ifndef STATIC_MODULES
|
||||||
|
|
||||||
|
#include <ltdl.h>
|
||||||
|
|
||||||
struct module **modlist = NULL;
|
struct module **modlist = NULL;
|
||||||
|
|
||||||
static const char *core_module_table[] = {
|
static const char *core_module_table[] = {
|
||||||
|
@ -101,6 +103,12 @@ struct Message modrestart_msgtab = {
|
||||||
void
|
void
|
||||||
modules_init(void)
|
modules_init(void)
|
||||||
{
|
{
|
||||||
|
if(lt_dlinit())
|
||||||
|
{
|
||||||
|
ilog(L_MAIN, "lt_dlinit failed");
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
mod_add_cmd(&modload_msgtab);
|
mod_add_cmd(&modload_msgtab);
|
||||||
mod_add_cmd(&modunload_msgtab);
|
mod_add_cmd(&modunload_msgtab);
|
||||||
mod_add_cmd(&modreload_msgtab);
|
mod_add_cmd(&modreload_msgtab);
|
||||||
|
@ -515,152 +523,6 @@ static void increase_modlist(void);
|
||||||
|
|
||||||
static char unknown_ver[] = "<unknown>";
|
static char unknown_ver[] = "<unknown>";
|
||||||
|
|
||||||
/* This file contains the core functions to use dynamic libraries.
|
|
||||||
* -TimeMr14C
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_MACH_O_DYLD_H
|
|
||||||
/*
|
|
||||||
** jmallett's dl*(3) shims for NSModule(3) systems.
|
|
||||||
*/
|
|
||||||
#include <mach-o/dyld.h>
|
|
||||||
|
|
||||||
#ifndef HAVE_DLOPEN
|
|
||||||
#ifndef RTLD_LAZY
|
|
||||||
#define RTLD_LAZY 2185 /* built-in dl*(3) don't care */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void undefinedErrorHandler(const char *);
|
|
||||||
NSModule multipleErrorHandler(NSSymbol, NSModule, NSModule);
|
|
||||||
void linkEditErrorHandler(NSLinkEditErrors, int, const char *, const char *);
|
|
||||||
char *dlerror(void);
|
|
||||||
void *dlopen(char *, int);
|
|
||||||
int dlclose(void *);
|
|
||||||
void *dlsym(void *, char *);
|
|
||||||
|
|
||||||
static int firstLoad = TRUE;
|
|
||||||
static int myDlError;
|
|
||||||
static char *myErrorTable[] = { "Loading file as object failed\n",
|
|
||||||
"Loading file as object succeeded\n",
|
|
||||||
"Not a valid shared object\n",
|
|
||||||
"Architecture of object invalid on this architecture\n",
|
|
||||||
"Invalid or corrupt image\n",
|
|
||||||
"Could not access object\n",
|
|
||||||
"NSCreateObjectFileImageFromFile failed\n",
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
|
|
||||||
void
|
|
||||||
undefinedErrorHandler(const char *symbolName)
|
|
||||||
{
|
|
||||||
sendto_realops_snomask(SNO_GENERAL, L_ALL, "Undefined symbol: %s", symbolName);
|
|
||||||
ilog(L_MAIN, "Undefined symbol: %s", symbolName);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
NSModule
|
|
||||||
multipleErrorHandler(NSSymbol s, NSModule old, NSModule new)
|
|
||||||
{
|
|
||||||
/* XXX
|
|
||||||
** This results in substantial leaking of memory... Should free one
|
|
||||||
** module, maybe?
|
|
||||||
*/
|
|
||||||
sendto_realops_snomask(SNO_GENERAL, L_ALL,
|
|
||||||
"Symbol `%s' found in `%s' and `%s'",
|
|
||||||
NSNameOfSymbol(s), NSNameOfModule(old), NSNameOfModule(new));
|
|
||||||
ilog(L_MAIN, "Symbol `%s' found in `%s' and `%s'",
|
|
||||||
NSNameOfSymbol(s), NSNameOfModule(old), NSNameOfModule(new));
|
|
||||||
/* We return which module should be considered valid, I believe */
|
|
||||||
return new;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
linkEditErrorHandler(NSLinkEditErrors errorClass, int errnum,
|
|
||||||
const char *fileName, const char *errorString)
|
|
||||||
{
|
|
||||||
sendto_realops_snomask(SNO_GENERAL, L_ALL,
|
|
||||||
"Link editor error: %s for %s", errorString, fileName);
|
|
||||||
ilog(L_MAIN, "Link editor error: %s for %s", errorString, fileName);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *
|
|
||||||
dlerror(void)
|
|
||||||
{
|
|
||||||
return myDlError == NSObjectFileImageSuccess ? NULL : myErrorTable[myDlError % 7];
|
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
|
||||||
dlopen(char *filename, int unused)
|
|
||||||
{
|
|
||||||
NSObjectFileImage myImage;
|
|
||||||
NSModule myModule;
|
|
||||||
|
|
||||||
if(firstLoad)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
** If we are loading our first symbol (huzzah!) we should go ahead
|
|
||||||
** and install link editor error handling!
|
|
||||||
*/
|
|
||||||
NSLinkEditErrorHandlers linkEditorErrorHandlers;
|
|
||||||
|
|
||||||
linkEditorErrorHandlers.undefined = undefinedErrorHandler;
|
|
||||||
linkEditorErrorHandlers.multiple = multipleErrorHandler;
|
|
||||||
linkEditorErrorHandlers.linkEdit = linkEditErrorHandler;
|
|
||||||
NSInstallLinkEditErrorHandlers(&linkEditorErrorHandlers);
|
|
||||||
firstLoad = FALSE;
|
|
||||||
}
|
|
||||||
myDlError = NSCreateObjectFileImageFromFile(filename, &myImage);
|
|
||||||
if(myDlError != NSObjectFileImageSuccess)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
myModule = NSLinkModule(myImage, filename, NSLINKMODULE_OPTION_PRIVATE);
|
|
||||||
return (void *) myModule;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
dlclose(void *myModule)
|
|
||||||
{
|
|
||||||
NSUnLinkModule(myModule, FALSE);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
|
||||||
dlsym(void *myModule, char *mySymbolName)
|
|
||||||
{
|
|
||||||
NSSymbol mySymbol;
|
|
||||||
|
|
||||||
mySymbol = NSLookupSymbolInModule((NSModule) myModule, mySymbolName);
|
|
||||||
return NSAddressOfSymbol(mySymbol);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* HPUX dl compat functions
|
|
||||||
*/
|
|
||||||
#if defined(HAVE_SHL_LOAD) && !defined(HAVE_DLOPEN)
|
|
||||||
#define RTLD_LAZY BIND_DEFERRED
|
|
||||||
#define RTLD_GLOBAL DYNAMIC_PATH
|
|
||||||
#define dlopen(file,mode) (void *)shl_load((file), (mode), (long) 0)
|
|
||||||
#define dlclose(handle) shl_unload((shl_t)(handle))
|
|
||||||
#define dlsym(handle,name) hpux_dlsym(handle,name)
|
|
||||||
#define dlerror() strerror(errno)
|
|
||||||
|
|
||||||
static void *
|
|
||||||
hpux_dlsym(void *handle, char *name)
|
|
||||||
{
|
|
||||||
void *sym_addr;
|
|
||||||
if(!shl_findsym((shl_t *) & handle, name, TYPE_UNDEFINED, &sym_addr))
|
|
||||||
return sym_addr;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* unload_one_module()
|
/* unload_one_module()
|
||||||
*
|
*
|
||||||
* inputs - name of module to unload
|
* inputs - name of module to unload
|
||||||
|
@ -722,7 +584,7 @@ unload_one_module(const char *name, int warn)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
dlclose(modlist[modindex]->address);
|
lt_dlclose(modlist[modindex]->address);
|
||||||
|
|
||||||
rb_free(modlist[modindex]->name);
|
rb_free(modlist[modindex]->name);
|
||||||
memmove(&modlist[modindex], &modlist[modindex + 1],
|
memmove(&modlist[modindex], &modlist[modindex + 1],
|
||||||
|
@ -751,8 +613,7 @@ unload_one_module(const char *name, int warn)
|
||||||
int
|
int
|
||||||
load_a_module(const char *path, int warn, int core)
|
load_a_module(const char *path, int warn, int core)
|
||||||
{
|
{
|
||||||
void *tmpptr = NULL;
|
lt_dlhandle tmpptr;
|
||||||
|
|
||||||
char *mod_basename;
|
char *mod_basename;
|
||||||
const char *ver;
|
const char *ver;
|
||||||
|
|
||||||
|
@ -760,15 +621,11 @@ load_a_module(const char *path, int warn, int core)
|
||||||
|
|
||||||
mod_basename = rb_basename(path);
|
mod_basename = rb_basename(path);
|
||||||
|
|
||||||
#ifdef CHARYBDIS_PROFILE
|
tmpptr = lt_dlopen(path);
|
||||||
tmpptr = dlopen(path, RTLD_NOW | RTLD_LOCAL | RTLD_PROFILE);
|
|
||||||
#else
|
|
||||||
tmpptr = dlopen(path, RTLD_NOW | RTLD_LOCAL);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if(tmpptr == NULL)
|
if(tmpptr == NULL)
|
||||||
{
|
{
|
||||||
const char *err = dlerror();
|
const char *err = lt_dlerror();
|
||||||
|
|
||||||
sendto_realops_snomask(SNO_GENERAL, L_ALL,
|
sendto_realops_snomask(SNO_GENERAL, L_ALL,
|
||||||
"Error loading module %s: %s", mod_basename, err);
|
"Error loading module %s: %s", mod_basename, err);
|
||||||
|
@ -784,16 +641,16 @@ load_a_module(const char *path, int warn, int core)
|
||||||
* as a single int in order to determine the API version.
|
* as a single int in order to determine the API version.
|
||||||
* -larne.
|
* -larne.
|
||||||
*/
|
*/
|
||||||
mapi_version = (int *) (uintptr_t) dlsym(tmpptr, "_mheader");
|
mapi_version = (int *) (uintptr_t) lt_dlsym(tmpptr, "_mheader");
|
||||||
if((mapi_version == NULL
|
if((mapi_version == NULL
|
||||||
&& (mapi_version = (int *) (uintptr_t) dlsym(tmpptr, "__mheader")) == NULL)
|
&& (mapi_version = (int *) (uintptr_t) lt_dlsym(tmpptr, "__mheader")) == NULL)
|
||||||
|| MAPI_MAGIC(*mapi_version) != MAPI_MAGIC_HDR)
|
|| MAPI_MAGIC(*mapi_version) != MAPI_MAGIC_HDR)
|
||||||
{
|
{
|
||||||
sendto_realops_snomask(SNO_GENERAL, L_ALL,
|
sendto_realops_snomask(SNO_GENERAL, L_ALL,
|
||||||
"Data format error: module %s has no MAPI header.",
|
"Data format error: module %s has no MAPI header.",
|
||||||
mod_basename);
|
mod_basename);
|
||||||
ilog(L_MAIN, "Data format error: module %s has no MAPI header.", mod_basename);
|
ilog(L_MAIN, "Data format error: module %s has no MAPI header.", mod_basename);
|
||||||
(void) dlclose(tmpptr);
|
(void) lt_dlclose(tmpptr);
|
||||||
rb_free(mod_basename);
|
rb_free(mod_basename);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -810,7 +667,7 @@ load_a_module(const char *path, int warn, int core)
|
||||||
sendto_realops_snomask(SNO_GENERAL, L_ALL,
|
sendto_realops_snomask(SNO_GENERAL, L_ALL,
|
||||||
"Module %s indicated failure during load.",
|
"Module %s indicated failure during load.",
|
||||||
mod_basename);
|
mod_basename);
|
||||||
dlclose(tmpptr);
|
lt_dlclose(tmpptr);
|
||||||
rb_free(mod_basename);
|
rb_free(mod_basename);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -845,7 +702,7 @@ load_a_module(const char *path, int warn, int core)
|
||||||
sendto_realops_snomask(SNO_GENERAL, L_ALL,
|
sendto_realops_snomask(SNO_GENERAL, L_ALL,
|
||||||
"Module %s has unknown/unsupported MAPI version %d.",
|
"Module %s has unknown/unsupported MAPI version %d.",
|
||||||
mod_basename, *mapi_version);
|
mod_basename, *mapi_version);
|
||||||
dlclose(tmpptr);
|
lt_dlclose(tmpptr);
|
||||||
rb_free(mod_basename);
|
rb_free(mod_basename);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue