ca74dd1996-10-08Fredrik Hübinette (Hubbe) #include "global.h"
2631a61996-10-09Fredrik Hübinette (Hubbe) #if !defined(HAVE_DLSYM) || !defined(HAVE_DLOPEN)
ca74dd1996-10-08Fredrik Hübinette (Hubbe) #undef HAVE_DLOPEN #endif
7860031997-01-22Bernhard Fastenrath #if !defined(HAVE_DLOPEN) && defined(HAVE_DLD_LINK) && defined(HAVE_DLD_GET_FUNC) #define USE_DLD #endif
6cf83a1997-02-06Fredrik Hübinette (Hubbe) #if 1
368fe71997-01-26Fredrik Hübinette (Hubbe) 
7860031997-01-22Bernhard Fastenrath #if defined(HAVE_DLOPEN) || defined(USE_DLD)
ca74dd1996-10-08Fredrik Hübinette (Hubbe) #include "interpret.h" #include "constants.h" #include "error.h" #include "module.h" #include "stralloc.h"
bb55f81997-03-16Fredrik Hübinette (Hubbe) #include "pike_macros.h"
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) 
7860031997-01-22Bernhard Fastenrath #ifdef HAVE_DLD_H #include <dld.h> #endif
6cf83a1997-02-06Fredrik Hübinette (Hubbe) typedef void (*modfun)(void);
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; #ifdef HAVE_DLOPEN #ifndef RTLD_NOW #define RTLD_NOW 0 #endif module=dlopen(module_name, RTLD_NOW); if(!module) { error("load_module(\"%s\") failed: %s\n", sp[-args].u.string->str, dlerror()); } #elif defined(USE_DLD) dld_create_reference("pike_module_init"); if (dld_link(module_name)) { error("load_module(\"%s\") failed: %s\n", module_name, dld_strerror(dld_errno)); } module=strdup(module_name); #endif /* HAVE_DLOPEN */ #ifdef HAVE_DLOPEN
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)  #elif defined(USE_DLD)
6cf83a1997-02-06Fredrik Hübinette (Hubbe)  init = (modfun)dld_get_func("pike_module_init"); exit = (modfun)dld_get_func("pike_module_exit");
368fe71997-01-26Fredrik Hübinette (Hubbe) #endif /* HAVE_DLOPEN */ if(!init || !exit) { #ifdef HAVE_DLOPEN dlclose(module); #elif defined(USE_DLD) dld_unlink_by_file((char *)module); free(module); #endif
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 */ void init_dynamic_load() { #ifdef USE_DLD if (dld_init(dld_find_executable("pike"))) /* should be argv[0] */ return; #endif #if defined(HAVE_DLOPEN) || defined(USE_DLD) add_efun("load_module",f_load_module,"function(string:program)",OPT_EXTERNAL_DEPEND); #endif } void exit_dynamic_load() { #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) #ifdef HAVE_DLOPEN dlclose(tmp->module);
7860031997-01-22Bernhard Fastenrath #elif defined(USE_DLD)
368fe71997-01-26Fredrik Hübinette (Hubbe)  if (tmp->module) { dld_unlink_by_file((char *)tmp->module, 1); free(tmp->module); } #endif free((char *)tmp); }
7860031997-01-22Bernhard Fastenrath #endif
368fe71997-01-26Fredrik Hübinette (Hubbe) } #else #if defined(HAVE_DLOPEN) || defined(USE_DLD) #include "interpret.h" #include "constants.h" #include "error.h" #include "module.h" #include "stralloc.h"
bb55f81997-03-16Fredrik Hübinette (Hubbe) #include "pike_macros.h"
368fe71997-01-26Fredrik Hübinette (Hubbe)  #ifdef HAVE_DLFCN_H #include <dlfcn.h> #endif #ifdef HAVE_DLD_H #include <dld.h> #endif struct module_list { struct module_list * next; void *module;
ca74dd1996-10-08Fredrik Hübinette (Hubbe)  struct module mod; }; struct module_list *dynamic_module_list = 0; void f_load_module(INT32 args) {
7860031997-01-22Bernhard Fastenrath #ifdef HAVE_DLOPEN
ca74dd1996-10-08Fredrik Hübinette (Hubbe)  void *module;
7860031997-01-22Bernhard Fastenrath #endif
ca74dd1996-10-08Fredrik Hübinette (Hubbe)  struct module_list *new_module;
7860031997-01-22Bernhard Fastenrath  const char *module_name;
235d1d1996-11-27Niels Möller  int res;
ca74dd1996-10-08Fredrik Hübinette (Hubbe)  if(sp[-args].type != T_STRING) error("Bad argument 1 to load_module()\n");
7860031997-01-22Bernhard Fastenrath  module_name = sp[-args].u.string->str; #ifdef HAVE_DLOPEN
7197641996-10-09Fredrik Hübinette (Hubbe) #ifndef RTLD_NOW #define RTLD_NOW 0 #endif
7860031997-01-22Bernhard Fastenrath  module=dlopen(module_name, RTLD_NOW);
ca74dd1996-10-08Fredrik Hübinette (Hubbe)  if(module)
7860031997-01-22Bernhard Fastenrath #endif /* HAVE_DLOPEN */
ca74dd1996-10-08Fredrik Hübinette (Hubbe)  { struct module *tmp;
798cd01996-10-12Fredrik Hübinette (Hubbe)  fun init, init2, exit;
7860031997-01-22Bernhard Fastenrath #ifdef HAVE_DLOPEN
798cd01996-10-12Fredrik Hübinette (Hubbe)  init=(fun)dlsym(module, "init_module_efuns"); init2=(fun)dlsym(module, "init_module_programs"); exit=(fun)dlsym(module, "exit_module");
ca74dd1996-10-08Fredrik Hübinette (Hubbe)  if(!init || !init2 || !exit)
7860031997-01-22Bernhard Fastenrath #endif /* HAVE_DLOPEN */
ca74dd1996-10-08Fredrik Hübinette (Hubbe)  { char *foo, buf1[1024], buf2[1024]; foo=STRRCHR(sp[-args].u.string->str,'/');
235d1d1996-11-27Niels Möller  if(foo) foo++; else foo=sp[-args].u.string->str;
ca74dd1996-10-08Fredrik Hübinette (Hubbe)  if(strlen(foo) < 1000) { strcpy(buf1, foo); foo=buf1;
0682ec1997-01-14Niels Möller  /* Strip extension, if any */ foo = STRCHR(foo, '.'); if (foo) *foo=0;
ca74dd1996-10-08Fredrik Hübinette (Hubbe)  strcpy(buf2,"init_"); strcat(buf2,buf1); strcat(buf2,"_efuns");
7860031997-01-22Bernhard Fastenrath #ifdef HAVE_DLOPEN
798cd01996-10-12Fredrik Hübinette (Hubbe)  init=(fun)dlsym(module, buf2);
7860031997-01-22Bernhard Fastenrath #elif defined(USE_DLD) dld_create_reference(buf2); if (dld_link(module_name)) { error("load_module(\"%s\") failed: %s\n", module_name, dld_strerror(dld_errno)); } init = (fun)dld_get_func(buf2); #endif /* USE_DLD */
ca74dd1996-10-08Fredrik Hübinette (Hubbe)  strcpy(buf2,"init_"); strcat(buf2,buf1); strcat(buf2,"_programs");
7860031997-01-22Bernhard Fastenrath #ifdef HAVE_DLOPEN
798cd01996-10-12Fredrik Hübinette (Hubbe)  init2=(fun)dlsym(module, buf2);
7860031997-01-22Bernhard Fastenrath #elif defined(USE_DLD) init2=(fun)dld_get_func(buf2); #endif
ca74dd1996-10-08Fredrik Hübinette (Hubbe)  strcpy(buf2,"exit_"); strcat(buf2,buf1);
7860031997-01-22Bernhard Fastenrath #ifdef HAVE_DLOPEN
798cd01996-10-12Fredrik Hübinette (Hubbe)  exit=(fun)dlsym(module, buf2);
7860031997-01-22Bernhard Fastenrath #elif defined(USE_DLD) exit=(fun)dld_get_func(buf2); #endif
ca74dd1996-10-08Fredrik Hübinette (Hubbe)  } } if(!init || !init2 || !exit) error("Failed to initialize module.\n"); new_module=ALLOC_STRUCT(module_list); new_module->next=dynamic_module_list; dynamic_module_list=new_module;
7860031997-01-22Bernhard Fastenrath #ifdef HAVE_DLOPEN
ca74dd1996-10-08Fredrik Hübinette (Hubbe)  new_module->module=module;
7860031997-01-22Bernhard Fastenrath #elif defined(USE_DLD) new_module->module_path = 0; new_module->module_path = xalloc(strlen(module_name) + 1); strcpy(new_module->module_path,module_name); #endif
ca74dd1996-10-08Fredrik Hübinette (Hubbe)  new_module->mod.init_efuns=init; new_module->mod.init_programs=init2; new_module->mod.exit=exit; new_module->mod.refs=0; tmp=current_module;
235d1d1996-11-27Niels Möller  current_module = & new_module->mod;
ca74dd1996-10-08Fredrik Hübinette (Hubbe)  (*(fun)init)(); (*(fun)init2)(); current_module=tmp;
235d1d1996-11-27Niels Möller  res = 1;
7860031997-01-22Bernhard Fastenrath  } #ifdef HAVE_DLOPEN else {
a69b791996-12-28Henrik Grubbström (Grubba)  error("load_module(\"%s\") failed: %s\n", sp[-args].u.string->str, dlerror()); }
7860031997-01-22Bernhard Fastenrath #endif
235d1d1996-11-27Niels Möller  pop_n_elems(args); push_int(res);
ca74dd1996-10-08Fredrik Hübinette (Hubbe) }
7860031997-01-22Bernhard Fastenrath #endif /* HAVE_DLOPEN || USE_DLD */
ca74dd1996-10-08Fredrik Hübinette (Hubbe)  void init_dynamic_load() {
7860031997-01-22Bernhard Fastenrath #ifdef USE_DLD if (dld_init(dld_find_executable("pike"))) /* should be argv[0] */ return; #endif #if defined(HAVE_DLOPEN) || defined(USE_DLD)
ca74dd1996-10-08Fredrik Hübinette (Hubbe)  add_efun("load_module",f_load_module,"function(string:int)",OPT_SIDE_EFFECT); #endif } void exit_dynamic_load() {
7860031997-01-22Bernhard Fastenrath #if defined(HAVE_DLOPEN) || defined(USE_DLD)
ca74dd1996-10-08Fredrik Hübinette (Hubbe)  while(dynamic_module_list) { struct module_list *tmp=dynamic_module_list; dynamic_module_list=tmp->next; (*tmp->mod.exit)();
7860031997-01-22Bernhard Fastenrath #ifdef HAVE_DLOPEN
ca74dd1996-10-08Fredrik Hübinette (Hubbe)  dlclose(tmp->module);
7860031997-01-22Bernhard Fastenrath #elif defined(USE_DLD) if (tmp->module_path) {
368fe71997-01-26Fredrik Hübinette (Hubbe)  dld_unlink_by_file((char *)tmp->module, 1); free(tmp->module);
7860031997-01-22Bernhard Fastenrath  } #endif
ca74dd1996-10-08Fredrik Hübinette (Hubbe)  free((char *)tmp); } #endif }
368fe71997-01-26Fredrik Hübinette (Hubbe) #endif