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 #ifdef HAVE_DLOPEN #include "interpret.h" #include "constants.h" #include "error.h" #include "module.h" #include "stralloc.h" #include "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)  struct module_list { struct module_list * next; void *module; struct module mod; }; struct module_list *dynamic_module_list = 0; void f_load_module(INT32 args) { void *module; struct module_list *new_module;
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");
7197641996-10-09Fredrik Hübinette (Hubbe) #ifndef RTLD_NOW #define RTLD_NOW 0 #endif
ca74dd1996-10-08Fredrik Hübinette (Hubbe)  module=dlopen(sp[-args].u.string->str, RTLD_NOW); if(module) { struct module *tmp;
798cd01996-10-12Fredrik Hübinette (Hubbe)  fun init, init2, exit; 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) { 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");
798cd01996-10-12Fredrik Hübinette (Hubbe)  init=(fun)dlsym(module, buf2);
ca74dd1996-10-08Fredrik Hübinette (Hubbe)  strcpy(buf2,"init_"); strcat(buf2,buf1); strcat(buf2,"_programs");
798cd01996-10-12Fredrik Hübinette (Hubbe)  init2=(fun)dlsym(module, buf2);
ca74dd1996-10-08Fredrik Hübinette (Hubbe)  strcpy(buf2,"exit_"); strcat(buf2,buf1);
798cd01996-10-12Fredrik Hübinette (Hubbe)  exit=(fun)dlsym(module, buf2);
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; new_module->module=module; 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;
a69b791996-12-28Henrik Grubbström (Grubba)  } else { error("load_module(\"%s\") failed: %s\n", sp[-args].u.string->str, dlerror()); }
235d1d1996-11-27Niels Möller  pop_n_elems(args); push_int(res);
ca74dd1996-10-08Fredrik Hübinette (Hubbe) } #endif void init_dynamic_load() { #ifdef HAVE_DLOPEN add_efun("load_module",f_load_module,"function(string:int)",OPT_SIDE_EFFECT); #endif } void exit_dynamic_load() { #ifdef HAVE_DLOPEN while(dynamic_module_list) { struct module_list *tmp=dynamic_module_list; dynamic_module_list=tmp->next; (*tmp->mod.exit)(); dlclose(tmp->module); free((char *)tmp); } #endif }