e1195f | 1997-03-23 | Fredrik Hübinette (Hubbe) | | #ifndef TESTING
# include "global.h"
# include "interpret.h"
# include "constants.h"
# include "error.h"
# include "module.h"
# include "stralloc.h"
# include "pike_macros.h"
|
24ddc7 | 1998-03-28 | Henrik Grubbström (Grubba) | |
|
5aeade | 1999-02-01 | Per Hedbor | | RCSID("$Id: dynamic_load.c,v 1.32 1999/01/31 23:50:15 per Exp $");
|
24ddc7 | 1998-03-28 | Henrik Grubbström (Grubba) | |
|
79f71c | 1998-07-09 | Francesco Chemolli | | #endif /* !TESTING */
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif /* HAVE_ERRNO_H */
#ifdef HAVE_STRING_H
#include <string.h>
#endif /* HAVE_STRING_H */
|
ca74dd | 1996-10-08 | Fredrik Hübinette (Hubbe) | |
|
964949 | 1998-02-27 | Fredrik Hübinette (Hubbe) | | #if !defined(HAVE_DLOPEN)
#if defined(HAVE_DLD_LINK) && defined(HAVE_DLD_GET_FUNC)
|
786003 | 1997-01-22 | Bernhard Fastenrath | | #define USE_DLD
|
964949 | 1998-02-27 | Fredrik Hübinette (Hubbe) | | #define HAVE_SOME_DLOPEN
#define EMULATE_DLOPEN
#else
|
79f71c | 1998-07-09 | Francesco Chemolli | | #if defined(HAVE_SHL_LOAD) && defined(HAVE_DL_H)
#define USE_HPUX_DL
#define HAVE_SOME_DLOPEN
#define EMULATE_DLOPEN
#else
|
964949 | 1998-02-27 | Fredrik Hübinette (Hubbe) | | #if defined(HAVE_LOADLIBRARY) && defined(HAVE_FREELIBRARY) && \
defined(HAVE_GETPROCADDRESS) && defined(HAVE_WINBASE_H)
#define USE_LOADLIBRARY
#define HAVE_SOME_DLOPEN
#define EMULATE_DLOPEN
#endif
#endif
|
79f71c | 1998-07-09 | Francesco Chemolli | | #endif
|
964949 | 1998-02-27 | Fredrik Hübinette (Hubbe) | | #else
#define HAVE_SOME_DLOPEN
|
786003 | 1997-01-22 | Bernhard Fastenrath | | #endif
|
964949 | 1998-02-27 | Fredrik Hübinette (Hubbe) | |
#ifdef HAVE_SOME_DLOPEN
|
2631a6 | 1996-10-09 | Fredrik Hübinette (Hubbe) | |
|
e1195f | 1997-03-23 | Fredrik Hübinette (Hubbe) | | typedef void (*modfun)(void);
|
964949 | 1998-02-27 | Fredrik Hübinette (Hubbe) | | #ifdef USE_LOADLIBRARY
#include <windows.h>
static TCHAR *convert_string(char *str, int len)
{
int e;
TCHAR *ret=(TCHAR *)xalloc((len+1) * sizeof(TCHAR));
for(e=0;e<len;e++) ret[e]=EXTRACT_UCHAR(str+e);
ret[e]=0;
return ret;
}
static void *dlopen(char *foo, int how)
{
TCHAR *tmp;
HINSTANCE ret;
tmp=convert_string(foo, strlen(foo));
ret=LoadLibrary(tmp);
free((char *)tmp);
return (void *)ret;
}
static char * dlerror(void)
{
static char buffer[200];
sprintf(buffer,"LoadLibrary failed with error: %d",GetLastError());
return buffer;
}
static void *dlsym(void *module, char * function)
{
return (void *)GetProcAddress((HMODULE)module,
function);
}
static void dlclose(void *module)
{
FreeLibrary((HMODULE)module);
}
#define dlinit()
|
79f71c | 1998-07-09 | Francesco Chemolli | | #endif /* USE_LOADLIBRARY */
|
964949 | 1998-02-27 | Fredrik Hübinette (Hubbe) | |
|
e1195f | 1997-03-23 | Fredrik Hübinette (Hubbe) | | #ifdef USE_DLD
#include <dld.h>
|
79f71c | 1998-07-09 | Francesco Chemolli | | static void *dlopen(char *module_name, int how)
|
e1195f | 1997-03-23 | Fredrik Hübinette (Hubbe) | | {
dld_create_reference("pike_module_init");
if(dld_link(module_name))
{
return (void *)strdup(module_name);
}else{
return 0;
}
}
static char *dlerror(void)
{
return dld_strerror(dld_errno);
}
static void *dlsym(void *module, char *function)
{
return dld_get_func(function);
}
static void *dlclose(void *module)
{
if(!module) return;
dld_unlink_by_file((char *)module);
free(module);
}
static void dlinit(void)
{
extern char ** ARGV;
if(dld_init(dld_find_executable(ARGV[0])))
{
fprintf(stderr,"Failed to init dld\n");
exit(1);
}
}
|
79f71c | 1998-07-09 | Francesco Chemolli | | #endif /* USE_DLD */
#ifdef USE_HPUX_DL
#include <dl.h>
|
513a2b | 1998-07-09 | Henrik Grubbström (Grubba) | | #if defined(BIND_VERBOSE)
|
79f71c | 1998-07-09 | Francesco Chemolli | | #define RTLD_NOW BIND_IMMEDIATE | BIND_VERBOSE
#else
#define RTLD_NOW BIND_IMMEDIATE
|
513a2b | 1998-07-09 | Henrik Grubbström (Grubba) | | #endif /* BIND_VERBOSE */
|
79f71c | 1998-07-09 | Francesco Chemolli | |
extern int errno;
static void *dlopen(char *libname, int how)
{
shl_t lib;
lib = shl_load(libname, how, 0L);
return (void *)lib;
}
|
e1195f | 1997-03-23 | Fredrik Hübinette (Hubbe) | |
|
79f71c | 1998-07-09 | Francesco Chemolli | | static char *dlerror(void)
{
#ifdef HAVE_STRERROR
return strerror(errno);
#else
return "";
|
964949 | 1998-02-27 | Fredrik Hübinette (Hubbe) | | #endif
|
79f71c | 1998-07-09 | Francesco Chemolli | | }
static void *dlsym(void *module, char *function)
{
void *func;
int result;
shl_t mod = (shl_t)module;
result = shl_findsym(&mod, function, TYPE_UNDEFINED, &func);
if (result == -1)
return NULL;
return func;
}
static void dlclose(void *module)
{
shl_unload((shl_t)module);
}
#define dlinit()
#endif /* USE_HPUX_DL */
|
964949 | 1998-02-27 | Fredrik Hübinette (Hubbe) | |
#ifndef EMULATE_DLOPEN
|
2631a6 | 1996-10-09 | Fredrik Hübinette (Hubbe) | | #ifdef HAVE_DLFCN_H
|
ca74dd | 1996-10-08 | Fredrik Hübinette (Hubbe) | | #include <dlfcn.h>
|
2631a6 | 1996-10-09 | Fredrik Hübinette (Hubbe) | | #endif
|
ca74dd | 1996-10-08 | Fredrik Hübinette (Hubbe) | |
|
e1195f | 1997-03-23 | Fredrik Hübinette (Hubbe) | | #define dlinit()
|
79f71c | 1998-07-09 | Francesco Chemolli | | #endif /* !EMULATE_DLOPEN */
|
786003 | 1997-01-22 | Bernhard Fastenrath | |
|
58dd66 | 1998-09-18 | Fredrik Hübinette (Hubbe) | | #endif /* HAVE_SOME_DLOPEN */
|
e1195f | 1997-03-23 | Fredrik Hübinette (Hubbe) | | #ifndef RTLD_NOW
#define RTLD_NOW 0
#endif
|
5aeade | 1999-02-01 | Per Hedbor | | #ifndef RTLD_LAZY
#define RTLD_LAZY 0
#endif
#ifndef RTLD_GLOBAL
#define RTLD_GLOBAL 0
#endif
|
e1195f | 1997-03-23 | Fredrik Hübinette (Hubbe) | | #ifndef TESTING
|
79f71c | 1998-07-09 | Francesco Chemolli | | #if defined(HAVE_DLOPEN) || defined(USE_DLD) || defined(USE_HPUX_DL)
|
6cf83a | 1997-02-06 | Fredrik Hübinette (Hubbe) | |
|
ca74dd | 1996-10-08 | Fredrik Hübinette (Hubbe) | | struct module_list
{
struct module_list * next;
|
368fe7 | 1997-01-26 | Fredrik Hübinette (Hubbe) | | void *module;
|
6cf83a | 1997-02-06 | Fredrik Hübinette (Hubbe) | | modfun init, exit;
|
368fe7 | 1997-01-26 | Fredrik Hübinette (Hubbe) | | };
struct module_list *dynamic_module_list = 0;
void f_load_module(INT32 args)
{
|
ca74dd | 1996-10-08 | Fredrik Hübinette (Hubbe) | | void *module;
|
6cf83a | 1997-02-06 | Fredrik Hübinette (Hubbe) | | modfun init, exit;
|
368fe7 | 1997-01-26 | Fredrik Hübinette (Hubbe) | | struct module_list *new_module;
const char *module_name;
if(sp[-args].type != T_STRING)
error("Bad argument 1 to load_module()\n");
module_name = sp[-args].u.string->str;
|
5aeade | 1999-02-01 | Per Hedbor | | module=dlopen(module_name,
(d_flag?RTLD_NOW|RTLD_GLOBAL:RTLD_LAZY|RTLD_GLOBAL));
|
ef78b0 | 1997-11-03 | Henrik Grubbström (Grubba) | |
|
368fe7 | 1997-01-26 | Fredrik Hübinette (Hubbe) | | if(!module)
{
|
466a32 | 1997-09-07 | Henrik Grubbström (Grubba) | | const char *err = dlerror();
|
e1195f | 1997-03-23 | Fredrik Hübinette (Hubbe) | | if(!err) err = "Unknown reason";
|
14160c | 1998-05-15 | Henrik Grubbström (Grubba) | | if (sp[-args].u.string->len < 1024) {
error("load_module(\"%s\") failed: %s\n",
sp[-args].u.string->str, err);
} else {
error("load_module() failed: %s\n", err);
}
|
368fe7 | 1997-01-26 | Fredrik Hübinette (Hubbe) | | }
|
6cf83a | 1997-02-06 | Fredrik Hübinette (Hubbe) | | init=(modfun)dlsym(module, "pike_module_init");
|
fb84a7 | 1997-03-04 | Henrik Grubbström (Grubba) | | if (!init) {
init=(modfun)dlsym(module, "_pike_module_init");
}
|
6cf83a | 1997-02-06 | Fredrik Hübinette (Hubbe) | | exit=(modfun)dlsym(module, "pike_module_exit");
|
fb84a7 | 1997-03-04 | Henrik Grubbström (Grubba) | | if (!exit) {
exit=(modfun)dlsym(module, "_pike_module_exit");
}
|
368fe7 | 1997-01-26 | Fredrik Hübinette (Hubbe) | |
if(!init || !exit)
{
dlclose(module);
|
14160c | 1998-05-15 | Henrik Grubbström (Grubba) | |
|
b2b895 | 1998-05-15 | Henrik Grubbström (Grubba) | | if (strlen(module_name) < 1024) {
|
14160c | 1998-05-15 | Henrik Grubbström (Grubba) | | error("Failed to initialize dynamic module \"%s\".\n", module_name);
} else {
error("Failed to initialize dynamic module.\n");
}
|
368fe7 | 1997-01-26 | Fredrik Hübinette (Hubbe) | | }
new_module=ALLOC_STRUCT(module_list);
new_module->next=dynamic_module_list;
dynamic_module_list=new_module;
new_module->module=module;
|
6cf83a | 1997-02-06 | Fredrik Hübinette (Hubbe) | | new_module->init=init;
new_module->exit=exit;
|
368fe7 | 1997-01-26 | Fredrik Hübinette (Hubbe) | |
pop_n_elems(args);
start_new_program();
|
6cf83a | 1997-02-06 | Fredrik Hübinette (Hubbe) | | (*(modfun)init)();
push_program(end_program());
|
368fe7 | 1997-01-26 | Fredrik Hübinette (Hubbe) | | }
|
79f71c | 1998-07-09 | Francesco Chemolli | | #endif /* HAVE_DLOPEN || USE_DLD || USE_HPUX_DL */
|
368fe7 | 1997-01-26 | Fredrik Hübinette (Hubbe) | |
|
e1195f | 1997-03-23 | Fredrik Hübinette (Hubbe) | | void init_dynamic_load(void)
|
368fe7 | 1997-01-26 | Fredrik Hübinette (Hubbe) | | {
|
79f71c | 1998-07-09 | Francesco Chemolli | | #if defined(HAVE_DLOPEN) || defined(USE_DLD) || defined(USE_HPUX_DL)
|
e1195f | 1997-03-23 | Fredrik Hübinette (Hubbe) | | dlinit();
|
368fe7 | 1997-01-26 | Fredrik Hübinette (Hubbe) | |
add_efun("load_module",f_load_module,"function(string:program)",OPT_EXTERNAL_DEPEND);
#endif
}
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | void exit_dynamic_load(void)
|
368fe7 | 1997-01-26 | Fredrik Hübinette (Hubbe) | | {
|
79f71c | 1998-07-09 | Francesco Chemolli | | #if defined(HAVE_DLOPEN) || defined(USE_DLD) || defined(USE_HPUX_DL)
|
368fe7 | 1997-01-26 | Fredrik Hübinette (Hubbe) | | while(dynamic_module_list)
{
struct module_list *tmp=dynamic_module_list;
dynamic_module_list=tmp->next;
|
6cf83a | 1997-02-06 | Fredrik Hübinette (Hubbe) | | (*tmp->exit)();
|
3c0c28 | 1998-01-26 | Fredrik Hübinette (Hubbe) | | #ifndef DEBUG_MALLOC
|
368fe7 | 1997-01-26 | Fredrik Hübinette (Hubbe) | | dlclose(tmp->module);
|
3c0c28 | 1998-01-26 | Fredrik Hübinette (Hubbe) | | #endif
|
368fe7 | 1997-01-26 | Fredrik Hübinette (Hubbe) | | free((char *)tmp);
}
|
786003 | 1997-01-22 | Bernhard Fastenrath | | #endif
|
368fe7 | 1997-01-26 | Fredrik Hübinette (Hubbe) | | }
|
e1195f | 1997-03-23 | Fredrik Hübinette (Hubbe) | | #else /* TESTING */
#include <stdio.h>
|
368fe7 | 1997-01-26 | Fredrik Hübinette (Hubbe) | |
|
e1195f | 1997-03-23 | Fredrik Hübinette (Hubbe) | | int main()
|
368fe7 | 1997-01-26 | Fredrik Hübinette (Hubbe) | | {
|
e1195f | 1997-03-23 | Fredrik Hübinette (Hubbe) | | void *module,*fun;
dlinit();
module=dlopen("./myconftest.so",RTLD_NOW);
if(!module)
|
ca74dd | 1996-10-08 | Fredrik Hübinette (Hubbe) | | {
|
e1195f | 1997-03-23 | Fredrik Hübinette (Hubbe) | | fprintf(stderr,"Failed to link myconftest.so: %s\n",dlerror());
exit(1);
|
a69b79 | 1996-12-28 | Henrik Grubbström (Grubba) | | }
|
e1195f | 1997-03-23 | Fredrik Hübinette (Hubbe) | | fun=dlsym(module,"testfunc");
if(!fun) fun=dlsym(module,"_testfunc");
if(!fun)
|
ca74dd | 1996-10-08 | Fredrik Hübinette (Hubbe) | | {
|
e1195f | 1997-03-23 | Fredrik Hübinette (Hubbe) | | fprintf(stderr,"Failed to find function testfunc: %s\n",dlerror());
exit(1);
|
ca74dd | 1996-10-08 | Fredrik Hübinette (Hubbe) | | }
|
a99145 | 1997-07-08 | Fredrik Hübinette (Hubbe) | | fprintf(stderr,"Calling testfunc\n");
|
e1195f | 1997-03-23 | Fredrik Hübinette (Hubbe) | | ((void (*)(void))fun)();
|
a99145 | 1997-07-08 | Fredrik Hübinette (Hubbe) | | fprintf(stderr,"testfunc returned!\n");
|
e1195f | 1997-03-23 | Fredrik Hübinette (Hubbe) | | exit(1);
|
ca74dd | 1996-10-08 | Fredrik Hübinette (Hubbe) | | }
|
368fe7 | 1997-01-26 | Fredrik Hübinette (Hubbe) | | #endif
|