e1195f1997-03-23Fredrik 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" #endif
ca74dd1996-10-08Fredrik Hübinette (Hubbe) 
7860031997-01-22Bernhard Fastenrath #if !defined(HAVE_DLOPEN) && defined(HAVE_DLD_LINK) && defined(HAVE_DLD_GET_FUNC) #define USE_DLD #endif #if defined(HAVE_DLOPEN) || defined(USE_DLD)
2631a61996-10-09Fredrik Hübinette (Hubbe) 
e1195f1997-03-23Fredrik Hübinette (Hubbe) typedef void (*modfun)(void); #ifdef USE_DLD #include <dld.h> static void *dlopen(char *foo, int how) { 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); } } #else
2631a61996-10-09Fredrik Hübinette (Hubbe) #ifdef HAVE_DLFCN_H
ca74dd1996-10-08Fredrik Hübinette (Hubbe) #include <dlfcn.h>
2631a61996-10-09Fredrik Hübinette (Hubbe) #endif
ca74dd1996-10-08Fredrik Hübinette (Hubbe) 
e1195f1997-03-23Fredrik Hübinette (Hubbe) #define dlinit()
7860031997-01-22Bernhard Fastenrath #endif
e1195f1997-03-23Fredrik Hübinette (Hubbe) #ifndef RTLD_NOW #define RTLD_NOW 0 #endif
de16081997-06-03Fredrik Hübinette (Hubbe) 
e1195f1997-03-23Fredrik Hübinette (Hubbe) #endif /* HAVE_DLOPEN || USE_DLD */ #ifndef TESTING #if defined(HAVE_DLOPEN) || defined(USE_DLD)
6cf83a1997-02-06Fredrik Hübinette (Hubbe) 
ca74dd1996-10-08Fredrik Hübinette (Hubbe) struct module_list { struct module_list * next;
368fe71997-01-26Fredrik Hübinette (Hubbe)  void *module;
6cf83a1997-02-06Fredrik Hübinette (Hubbe)  modfun init, exit;
368fe71997-01-26Fredrik Hübinette (Hubbe) }; struct module_list *dynamic_module_list = 0; void f_load_module(INT32 args) {
ca74dd1996-10-08Fredrik Hübinette (Hubbe)  void *module;
6cf83a1997-02-06Fredrik Hübinette (Hubbe)  modfun init, exit;
368fe71997-01-26Fredrik 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; module=dlopen(module_name, RTLD_NOW); if(!module) {
e1195f1997-03-23Fredrik Hübinette (Hubbe)  char *err = dlerror(); if(!err) err = "Unknown reason";
368fe71997-01-26Fredrik Hübinette (Hubbe)  error("load_module(\"%s\") failed: %s\n",
58fa881997-03-23Niels Möller  sp[-args].u.string->str, err);
368fe71997-01-26Fredrik Hübinette (Hubbe)  }
6cf83a1997-02-06Fredrik Hübinette (Hubbe)  init=(modfun)dlsym(module, "pike_module_init");
fb84a71997-03-04Henrik Grubbström (Grubba)  if (!init) { init=(modfun)dlsym(module, "_pike_module_init"); }
6cf83a1997-02-06Fredrik Hübinette (Hubbe)  exit=(modfun)dlsym(module, "pike_module_exit");
fb84a71997-03-04Henrik Grubbström (Grubba)  if (!exit) { exit=(modfun)dlsym(module, "_pike_module_exit"); }
368fe71997-01-26Fredrik Hübinette (Hubbe)  if(!init || !exit) { dlclose(module);
24697f1997-03-12Henrik Grubbström (Grubba)  error("Failed to initialize module \"%s\".\n", module_name);
368fe71997-01-26Fredrik Hübinette (Hubbe)  } new_module=ALLOC_STRUCT(module_list); new_module->next=dynamic_module_list; dynamic_module_list=new_module; new_module->module=module;
6cf83a1997-02-06Fredrik Hübinette (Hubbe)  new_module->init=init; new_module->exit=exit;
368fe71997-01-26Fredrik Hübinette (Hubbe)  pop_n_elems(args); start_new_program();
6cf83a1997-02-06Fredrik Hübinette (Hubbe)  (*(modfun)init)(); push_program(end_program());
368fe71997-01-26Fredrik Hübinette (Hubbe) } #endif /* HAVE_DLOPEN || USE_DLD */
e1195f1997-03-23Fredrik Hübinette (Hubbe) void init_dynamic_load(void)
368fe71997-01-26Fredrik Hübinette (Hubbe) {
b298e01997-04-16Fredrik Hübinette (Hubbe) #if defined(HAVE_DLOPEN) || defined(USE_DLD)
e1195f1997-03-23Fredrik Hübinette (Hubbe)  dlinit();
368fe71997-01-26Fredrik Hübinette (Hubbe)  add_efun("load_module",f_load_module,"function(string:program)",OPT_EXTERNAL_DEPEND); #endif }
be478c1997-08-30Henrik Grubbström (Grubba) void exit_dynamic_load(void)
368fe71997-01-26Fredrik Hübinette (Hubbe) { #if defined(HAVE_DLOPEN) || defined(USE_DLD) while(dynamic_module_list) { struct module_list *tmp=dynamic_module_list; dynamic_module_list=tmp->next;
6cf83a1997-02-06Fredrik Hübinette (Hubbe)  (*tmp->exit)();
368fe71997-01-26Fredrik Hübinette (Hubbe)  dlclose(tmp->module); free((char *)tmp); }
7860031997-01-22Bernhard Fastenrath #endif
368fe71997-01-26Fredrik Hübinette (Hubbe) }
e1195f1997-03-23Fredrik Hübinette (Hubbe) #else /* TESTING */ #include <stdio.h>
368fe71997-01-26Fredrik Hübinette (Hubbe) 
e1195f1997-03-23Fredrik Hübinette (Hubbe) int main()
368fe71997-01-26Fredrik Hübinette (Hubbe) {
e1195f1997-03-23Fredrik Hübinette (Hubbe)  void *module,*fun; dlinit(); module=dlopen("./myconftest.so",RTLD_NOW); if(!module)
ca74dd1996-10-08Fredrik Hübinette (Hubbe)  {
e1195f1997-03-23Fredrik Hübinette (Hubbe)  fprintf(stderr,"Failed to link myconftest.so: %s\n",dlerror()); exit(1);
a69b791996-12-28Henrik Grubbström (Grubba)  }
e1195f1997-03-23Fredrik Hübinette (Hubbe)  fun=dlsym(module,"testfunc"); if(!fun) fun=dlsym(module,"_testfunc"); if(!fun)
ca74dd1996-10-08Fredrik Hübinette (Hubbe)  {
e1195f1997-03-23Fredrik Hübinette (Hubbe)  fprintf(stderr,"Failed to find function testfunc: %s\n",dlerror()); exit(1);
ca74dd1996-10-08Fredrik Hübinette (Hubbe)  }
a991451997-07-08Fredrik Hübinette (Hubbe)  fprintf(stderr,"Calling testfunc\n");
e1195f1997-03-23Fredrik Hübinette (Hubbe)  ((void (*)(void))fun)();
a991451997-07-08Fredrik Hübinette (Hubbe)  fprintf(stderr,"testfunc returned!\n");
e1195f1997-03-23Fredrik Hübinette (Hubbe)  exit(1);
ca74dd1996-10-08Fredrik Hübinette (Hubbe) }
368fe71997-01-26Fredrik Hübinette (Hubbe) #endif