e1195f | 1997-03-23 | Fredrik Hübinette (Hubbe) | | #ifndef TESTING
# include "global.h"
# include "interpret.h"
# include "constants.h"
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | # include "pike_error.h"
|
e1195f | 1997-03-23 | Fredrik Hübinette (Hubbe) | | # include "module.h"
# include "stralloc.h"
# include "pike_macros.h"
|
655982 | 1999-02-01 | Per Hedbor | | # include "main.h"
|
24ddc7 | 1998-03-28 | Henrik Grubbström (Grubba) | |
|
8c953a | 2001-03-28 | Henrik Grubbström (Grubba) | | RCSID("$Id: dynamic_load.c,v 1.52 2001/03/28 15:07:38 grubba 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
|
1c0ff3 | 2000-12-18 | Fredrik Hübinette (Hubbe) | |
#if 0
|
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
|
1c0ff3 | 2000-12-18 | Fredrik Hübinette (Hubbe) | | #endif /* 0 */
|
9b15e0 | 2000-12-22 | Fredrik Hübinette (Hubbe) | | #ifdef USE_MY_WIN32_DLOPEN
#include "pike_dlfcn.h"
#define HAVE_SOME_DLOPEN
#define HAVE_DLOPEN
#endif
|
964949 | 1998-02-27 | Fredrik Hübinette (Hubbe) | | #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>
|
c7241b | 2000-08-10 | Henrik Grubbström (Grubba) | | static TCHAR *convert_string(const char *str, ptrdiff_t len)
|
964949 | 1998-02-27 | Fredrik Hübinette (Hubbe) | | {
|
c7241b | 2000-08-10 | Henrik Grubbström (Grubba) | | ptrdiff_t e;
|
964949 | 1998-02-27 | Fredrik Hübinette (Hubbe) | | 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;
}
|
01a957 | 2000-02-03 | Henrik Grubbström (Grubba) | | static void *dlopen(const char *foo, int how)
|
964949 | 1998-02-27 | Fredrik Hübinette (Hubbe) | | {
TCHAR *tmp;
HINSTANCE ret;
tmp=convert_string(foo, strlen(foo));
ret=LoadLibrary(tmp);
free((char *)tmp);
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | if(ret)
{
void ** psym=(void **)GetProcAddress(ret, "PikeSymbol");
if(psym)
{
extern void *PikeSymbol[];
*psym = PikeSymbol;
}
}
|
964949 | 1998-02-27 | Fredrik Hübinette (Hubbe) | | return (void *)ret;
}
static char * dlerror(void)
{
static char buffer[200];
|
a4a172 | 2000-12-05 | Per Hedbor | | sprintf(buffer,"LoadLibrary failed with error: %d",GetLastError());
|
964949 | 1998-02-27 | Fredrik Hübinette (Hubbe) | | 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>
|
01a957 | 2000-02-03 | Henrik Grubbström (Grubba) | | static void *dlopen(const 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;
|
01a957 | 2000-02-03 | Henrik Grubbström (Grubba) | | static void *dlopen(const char *libname, int how)
|
79f71c | 1998-07-09 | Francesco Chemolli | | {
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
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | #if defined(HAVE_DLOPEN) || defined(USE_DLD) || defined(USE_HPUX_DL) || defined(USE_LOADLIBRARY)
|
e00cc8 | 2000-09-29 | Martin Stjernholm | | #define USE_DYNAMIC_MODULES
#endif
#ifdef USE_DYNAMIC_MODULES
|
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;
|
418a37 | 1999-04-25 | Henrik Grubbström (Grubba) | | #ifdef NO_CAST_TO_FUN
static modfun CAST_TO_FUN(void *ptr)
{
union {
void *ptr;
modfun fun;
} u;
u.ptr = ptr;
return u.fun;
}
#else /* !NO_CAST_TO_FUN */
#define CAST_TO_FUN(X) ((modfun)X)
#endif /* NO_CAST_TO_FUN */
|
7c0df7 | 2001-02-06 | Henrik Grubbström (Grubba) | |
|
368fe7 | 1997-01-26 | Fredrik Hübinette (Hubbe) | | 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)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Bad argument 1 to load_module()\n");
|
368fe7 | 1997-01-26 | Fredrik Hübinette (Hubbe) | |
module_name = sp[-args].u.string->str;
|
081930 | 2000-02-17 | Fredrik Hübinette (Hubbe) | |
|
8bff49 | 2000-09-26 | Fredrik Hübinette (Hubbe) | |
|
5aeade | 1999-02-01 | Per Hedbor | | module=dlopen(module_name,
|
8bff49 | 2000-09-26 | Fredrik Hübinette (Hubbe) | | RTLD_NOW |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) {
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("load_module(\"%s\") failed: %s\n",
|
14160c | 1998-05-15 | Henrik Grubbström (Grubba) | | sp[-args].u.string->str, err);
} else {
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("load_module() failed: %s\n", err);
|
14160c | 1998-05-15 | Henrik Grubbström (Grubba) | | }
|
368fe7 | 1997-01-26 | Fredrik Hübinette (Hubbe) | | }
|
418a37 | 1999-04-25 | Henrik Grubbström (Grubba) | | init = CAST_TO_FUN(dlsym(module, "pike_module_init"));
|
fb84a7 | 1997-03-04 | Henrik Grubbström (Grubba) | | if (!init) {
|
418a37 | 1999-04-25 | Henrik Grubbström (Grubba) | | init = CAST_TO_FUN(dlsym(module, "_pike_module_init"));
|
fb84a7 | 1997-03-04 | Henrik Grubbström (Grubba) | | }
|
418a37 | 1999-04-25 | Henrik Grubbström (Grubba) | | exit = CAST_TO_FUN(dlsym(module, "pike_module_exit"));
|
fb84a7 | 1997-03-04 | Henrik Grubbström (Grubba) | | if (!exit) {
|
418a37 | 1999-04-25 | Henrik Grubbström (Grubba) | | exit = CAST_TO_FUN(dlsym(module, "_pike_module_exit"));
|
fb84a7 | 1997-03-04 | Henrik Grubbström (Grubba) | | }
|
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) {
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Failed to initialize dynamic module \"%s\".\n", module_name);
|
14160c | 1998-05-15 | Henrik Grubbström (Grubba) | | } else {
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Failed to initialize dynamic module.\n");
|
14160c | 1998-05-15 | Henrik Grubbström (Grubba) | | }
|
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) | |
start_new_program();
|
044c62 | 1999-04-14 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
{ struct svalue *save_sp=sp;
#endif
|
6cf83a | 1997-02-06 | Fredrik Hübinette (Hubbe) | | (*(modfun)init)();
|
044c62 | 1999-04-14 | Fredrik Hübinette (Hubbe) | | #ifdef PIKE_DEBUG
if(sp != save_sp)
|
6f9590 | 2000-08-17 | Henrik Grubbström (Grubba) | | fatal("load_module(%s) left %ld droppings on stack!\n",
|
044c62 | 1999-04-14 | Fredrik Hübinette (Hubbe) | | module_name,
|
6f9590 | 2000-08-17 | Henrik Grubbström (Grubba) | | PTRDIFF_T_TO_LONG(sp - save_sp));
|
044c62 | 1999-04-14 | Fredrik Hübinette (Hubbe) | | }
#endif
|
6cf83a | 1997-02-06 | Fredrik Hübinette (Hubbe) | |
|
044c62 | 1999-04-14 | Fredrik Hübinette (Hubbe) | | pop_n_elems(args);
|
6cf83a | 1997-02-06 | Fredrik Hübinette (Hubbe) | | push_program(end_program());
|
368fe7 | 1997-01-26 | Fredrik Hübinette (Hubbe) | | }
|
e00cc8 | 2000-09-29 | Martin Stjernholm | | #endif /* USE_DYNAMIC_MODULES */
|
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) | | {
|
e00cc8 | 2000-09-29 | Martin Stjernholm | | #ifdef USE_DYNAMIC_MODULES
|
e1195f | 1997-03-23 | Fredrik Hübinette (Hubbe) | | dlinit();
|
368fe7 | 1997-01-26 | Fredrik Hübinette (Hubbe) | |
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | |
|
1f2133 | 2000-07-28 | Fredrik Hübinette (Hubbe) | |
|
8c953a | 2001-03-28 | Henrik Grubbström (Grubba) | | ADD_EFUN("load_module",f_load_module,tFunc(tStr,tPrg(tObj)),OPT_EXTERNAL_DEPEND);
|
368fe7 | 1997-01-26 | Fredrik Hübinette (Hubbe) | | #endif
}
|
da667d | 2000-09-28 | Henrik Grubbström (Grubba) | |
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | void exit_dynamic_load(void)
|
368fe7 | 1997-01-26 | Fredrik Hübinette (Hubbe) | | {
|
e00cc8 | 2000-09-29 | Martin Stjernholm | | #ifdef USE_DYNAMIC_MODULES
struct module_list *tmp;
for (tmp = dynamic_module_list; tmp; tmp = tmp->next)
|
6cf83a | 1997-02-06 | Fredrik Hübinette (Hubbe) | | (*tmp->exit)();
|
da667d | 2000-09-28 | Henrik Grubbström (Grubba) | | #endif
}
void free_dynamic_load(void)
{
|
e00cc8 | 2000-09-29 | Martin Stjernholm | | #ifdef USE_DYNAMIC_MODULES
|
da667d | 2000-09-28 | Henrik Grubbström (Grubba) | | while(dynamic_module_list)
{
struct module_list *tmp=dynamic_module_list;
dynamic_module_list=tmp->next;
|
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
|