Branch: Tag:

1997-03-24

1997-03-24 00:44:37 by Fredrik Hübinette (Hubbe) <hubbe@hubbe.net>

added a configure test for dynamic loading

Rev: src/ChangeLog:1.92
Rev: src/configure.in:1.64
Rev: src/dynamic_load.c:1.15
Rev: src/main.c:1.20

1: - #include "global.h" + #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      #if !defined(HAVE_DLSYM) || !defined(HAVE_DLOPEN)   #undef HAVE_DLOPEN
8:   #define USE_DLD   #endif    - #if 1 -  +    #if defined(HAVE_DLOPEN) || defined(USE_DLD) - #include "interpret.h" - #include "constants.h" - #include "error.h" - #include "module.h" - #include "stralloc.h" - #include "pike_macros.h" +     -  + 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   #ifdef HAVE_DLFCN_H   #include <dlfcn.h>   #endif    - #ifdef HAVE_DLD_H - #include <dld.h> + #define dlinit()   #endif    - typedef void (*modfun)(void); + #ifndef RTLD_NOW + #define RTLD_NOW 0 + #endif    -  + #endif /* HAVE_DLOPEN || USE_DLD */ +  + #ifndef TESTING +  + #if defined(HAVE_DLOPEN) || defined(USE_DLD) +    struct module_list   {    struct module_list * next;
49:       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)    { -  char *err = dlerror(); -  if (err) -  err = ""; +  char *err = dlerror(); +  if(!err) err = "Unknown reason";    error("load_module(\"%s\") failed: %s\n",    sp[-args].u.string->str, err);    } - #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 +     init=(modfun)dlsym(module, "pike_module_init");    if (!init) {    init=(modfun)dlsym(module, "_pike_module_init");
82: Inside #if defined(HAVE_DLOPEN)
   exit=(modfun)dlsym(module, "_pike_module_exit");    }    - #elif defined(USE_DLD) -  init = (modfun)dld_get_func("pike_module_init"); -  exit = (modfun)dld_get_func("pike_module_exit"); - #endif /* HAVE_DLOPEN */ -  +     if(!init || !exit)    { - #ifdef HAVE_DLOPEN +     dlclose(module); - #elif defined(USE_DLD) -  dld_unlink_by_file((char *)module); -  free(module); - #endif +        error("Failed to initialize module \"%s\".\n", module_name);    }
116:      #endif /* HAVE_DLOPEN || USE_DLD */    - void init_dynamic_load() + void init_dynamic_load(void)   { - #ifdef USE_DLD -  if (dld_init(dld_find_executable("pike"))) /* should be argv[0] */ -  return; - #endif +  dlinit();      #if defined(HAVE_DLOPEN) || defined(USE_DLD)    add_efun("load_module",f_load_module,"function(string:program)",OPT_EXTERNAL_DEPEND);
136: Inside #if defined(HAVE_DLOPEN) || defined(USE_DLD)
   struct module_list *tmp=dynamic_module_list;    dynamic_module_list=tmp->next;    (*tmp->exit)(); - #ifdef HAVE_DLOPEN +     dlclose(tmp->module); - #elif defined(USE_DLD) -  if (tmp->module) { -  dld_unlink_by_file((char *)tmp->module, 1); -  free(tmp->module); -  } - #endif +     free((char *)tmp);    }   #endif   }       - #else + #else /* TESTING */ + #include <stdio.h>    - #if defined(HAVE_DLOPEN) || defined(USE_DLD) - #include "interpret.h" - #include "constants.h" - #include "error.h" - #include "module.h" - #include "stralloc.h" - #include "pike_macros.h" -  - #ifdef HAVE_DLFCN_H - #include <dlfcn.h> - #endif -  - #ifdef HAVE_DLD_H - #include <dld.h> - #endif -  - struct module_list + int main()   { -  struct module_list * next; -  void *module; -  struct module mod; - }; -  - struct module_list *dynamic_module_list = 0; -  - void f_load_module(INT32 args) +  void *module,*fun; +  dlinit(); +  module=dlopen("./myconftest.so",RTLD_NOW); +  if(!module)    { - #ifdef HAVE_DLOPEN -  void *module; - #endif -  struct module_list *new_module; -  const char *module_name; -  int res; -  -  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) - #endif /* HAVE_DLOPEN */ -  { -  struct module *tmp; -  fun init, init2, exit; -  - #ifdef HAVE_DLOPEN -  init=(fun)dlsym(module, "init_module_efuns"); -  init2=(fun)dlsym(module, "init_module_programs"); -  exit=(fun)dlsym(module, "exit_module"); -  -  if(!init || !init2 || !exit) - #endif /* HAVE_DLOPEN */ -  { -  char *foo, buf1[1024], buf2[1024]; -  foo=STRRCHR(sp[-args].u.string->str,'/'); -  if(foo) -  foo++; -  else -  foo=sp[-args].u.string->str; -  if(strlen(foo) < 1000) -  { -  strcpy(buf1, foo); -  foo=buf1; -  -  /* Strip extension, if any */ -  foo = STRCHR(foo, '.'); -  if (foo) -  *foo=0; -  -  strcpy(buf2,"init_"); -  strcat(buf2,buf1); -  strcat(buf2,"_efuns"); - #ifdef HAVE_DLOPEN -  init=(fun)dlsym(module, buf2); - #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)); +  fprintf(stderr,"Failed to link myconftest.so: %s\n",dlerror()); +  exit(1);    } -  init = (fun)dld_get_func(buf2); - #endif /* USE_DLD */ -  -  strcpy(buf2,"init_"); -  strcat(buf2,buf1); -  strcat(buf2,"_programs"); - #ifdef HAVE_DLOPEN -  init2=(fun)dlsym(module, buf2); - #elif defined(USE_DLD) -  init2=(fun)dld_get_func(buf2); - #endif -  -  strcpy(buf2,"exit_"); -  strcat(buf2,buf1); - #ifdef HAVE_DLOPEN -  exit=(fun)dlsym(module, buf2); - #elif defined(USE_DLD) -  exit=(fun)dld_get_func(buf2); - #endif -  } -  } -  -  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; - #ifdef HAVE_DLOPEN -  new_module->module=module; - #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 -  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; -  current_module = & new_module->mod; -  -  (*(fun)init)(); -  (*(fun)init2)(); -  -  current_module=tmp; -  -  res = 1; -  } - #ifdef HAVE_DLOPEN -  else { -  error("load_module(\"%s\") failed: %s\n", -  sp[-args].u.string->str, dlerror()); -  } - #endif -  pop_n_elems(args); -  push_int(res); - } -  -  - #endif /* HAVE_DLOPEN || USE_DLD */ -  - void init_dynamic_load() +  fun=dlsym(module,"testfunc"); +  if(!fun) fun=dlsym(module,"_testfunc"); +  if(!fun)    { - #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:int)",OPT_SIDE_EFFECT); - #endif +  fprintf(stderr,"Failed to find function testfunc: %s\n",dlerror()); +  exit(1);    } -  - 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; -  (*tmp->mod.exit)(); - #ifdef HAVE_DLOPEN -  dlclose(tmp->module); - #elif defined(USE_DLD) -  if (tmp->module_path) { -  dld_unlink_by_file((char *)tmp->module, 1); -  free(tmp->module); +  ((void (*)(void))fun)(); +  exit(1);   }   #endif -  free((char *)tmp); -  } - #endif - } -  -  - #endif +