e576bb2002-10-11Martin Nilsson /* || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information.
8853882008-04-26Henrik Grubbström (Grubba) || $Id: dynamic_load.c,v 1.91 2008/04/26 19:04:25 grubba Exp $
e576bb2002-10-11Martin Nilsson */
1b10db2002-10-08Martin Nilsson 
56f4f42001-09-18Fredrik Hübinette (Hubbe) #ifdef TESTING #define NO_PIKE_INCLUDES #define CREATE_MAIN #define NO_PIKE_GUTS #endif #ifndef NO_PIKE_INCLUDES
e1195f1997-03-23Fredrik Hübinette (Hubbe) # include "global.h" # include "interpret.h" # include "constants.h"
b2d3e42000-12-01Fredrik Hübinette (Hubbe) # include "pike_error.h"
e1195f1997-03-23Fredrik Hübinette (Hubbe) # include "module.h" # include "stralloc.h" # include "pike_macros.h"
6559821999-02-01Per Hedbor # include "main.h"
c39e432001-08-02Fredrik Hübinette (Hubbe) # include "constants.h"
37b0222002-01-31Marcus Comstedt # include "lex.h"
20b5222004-03-22Martin Stjernholm # include "object.h"
24ddc71998-03-28Henrik Grubbström (Grubba) 
ecf1552001-09-10Henrik Grubbström (Grubba) #else /* TESTING */ #include <stdio.h>
24ddc71998-03-28Henrik Grubbström (Grubba) 
79f71c1998-07-09Francesco 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 */
ca74dd1996-10-08Fredrik Hübinette (Hubbe) 
9649491998-02-27Fredrik Hübinette (Hubbe) #if !defined(HAVE_DLOPEN) #if defined(HAVE_DLD_LINK) && defined(HAVE_DLD_GET_FUNC)
7860031997-01-22Bernhard Fastenrath #define USE_DLD
9649491998-02-27Fredrik Hübinette (Hubbe) #define HAVE_SOME_DLOPEN #define EMULATE_DLOPEN #else
79f71c1998-07-09Francesco Chemolli #if defined(HAVE_SHL_LOAD) && defined(HAVE_DL_H) #define USE_HPUX_DL #define HAVE_SOME_DLOPEN #define EMULATE_DLOPEN #else
1c0ff32000-12-18Fredrik Hübinette (Hubbe) 
13d6bc2006-07-05Martin Stjernholm #ifdef USE_DLL
9649491998-02-27Fredrik 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
13d6bc2006-07-05Martin Stjernholm #endif
1c0ff32000-12-18Fredrik Hübinette (Hubbe) 
ecf1552001-09-10Henrik Grubbström (Grubba) #ifdef HAVE_MACH_O_DYLD_H /* MacOS X... */ #define USE_DYLD #define HAVE_SOME_DLOPEN #define EMULATE_DLOPEN #else /* !HAVE_MACH_O_DYLD_H */
13d6bc2006-07-05Martin Stjernholm #if !defined (USE_DLL) && defined (USE_MY_WIN32_DLOPEN)
9b15e02000-12-22Fredrik Hübinette (Hubbe) #include "pike_dlfcn.h" #define HAVE_SOME_DLOPEN #define HAVE_DLOPEN #endif
ecf1552001-09-10Henrik Grubbström (Grubba) #endif /* HAVE_MACH_O_DYLD_H */
9b15e02000-12-22Fredrik Hübinette (Hubbe) 
9649491998-02-27Fredrik Hübinette (Hubbe) #endif
79f71c1998-07-09Francesco Chemolli #endif
9649491998-02-27Fredrik Hübinette (Hubbe) #else #define HAVE_SOME_DLOPEN
7860031997-01-22Bernhard Fastenrath #endif
9649491998-02-27Fredrik Hübinette (Hubbe)  #ifdef HAVE_SOME_DLOPEN
2631a61996-10-09Fredrik Hübinette (Hubbe) 
e1195f1997-03-23Fredrik Hübinette (Hubbe) typedef void (*modfun)(void);
9649491998-02-27Fredrik Hübinette (Hubbe) #ifdef USE_LOADLIBRARY #include <windows.h>
c7241b2000-08-10Henrik Grubbström (Grubba) static TCHAR *convert_string(const char *str, ptrdiff_t len)
9649491998-02-27Fredrik Hübinette (Hubbe) {
c7241b2000-08-10Henrik Grubbström (Grubba)  ptrdiff_t e;
9649491998-02-27Fredrik 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; }
01a9572000-02-03Henrik Grubbström (Grubba) static void *dlopen(const char *foo, int how)
9649491998-02-27Fredrik Hübinette (Hubbe) { TCHAR *tmp; HINSTANCE ret; tmp=convert_string(foo, strlen(foo)); ret=LoadLibrary(tmp); free((char *)tmp); return (void *)ret; } static char * dlerror(void) { static char buffer[200];
a4a1722000-12-05Per Hedbor  sprintf(buffer,"LoadLibrary failed with error: %d",GetLastError());
9649491998-02-27Fredrik 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); }
ecf1552001-09-10Henrik Grubbström (Grubba) #define dlinit() 1
9649491998-02-27Fredrik Hübinette (Hubbe) 
79f71c1998-07-09Francesco Chemolli #endif /* USE_LOADLIBRARY */
9649491998-02-27Fredrik Hübinette (Hubbe) 
e1195f1997-03-23Fredrik Hübinette (Hubbe) #ifdef USE_DLD #include <dld.h>
01a9572000-02-03Henrik Grubbström (Grubba) static void *dlopen(const char *module_name, int how)
e1195f1997-03-23Fredrik 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); }
ecf1552001-09-10Henrik Grubbström (Grubba) static int dlinit(void)
e1195f1997-03-23Fredrik Hübinette (Hubbe) { extern char ** ARGV; if(dld_init(dld_find_executable(ARGV[0]))) { fprintf(stderr,"Failed to init dld\n");
ecf1552001-09-10Henrik Grubbström (Grubba)  return 0;
e1195f1997-03-23Fredrik Hübinette (Hubbe)  }
ecf1552001-09-10Henrik Grubbström (Grubba)  /* OK */ return 1;
e1195f1997-03-23Fredrik Hübinette (Hubbe) }
79f71c1998-07-09Francesco Chemolli #endif /* USE_DLD */ #ifdef USE_HPUX_DL #include <dl.h>
513a2b1998-07-09Henrik Grubbström (Grubba) #if defined(BIND_VERBOSE)
79f71c1998-07-09Francesco Chemolli #define RTLD_NOW BIND_IMMEDIATE | BIND_VERBOSE #else #define RTLD_NOW BIND_IMMEDIATE
513a2b1998-07-09Henrik Grubbström (Grubba) #endif /* BIND_VERBOSE */
79f71c1998-07-09Francesco Chemolli  extern int errno;
01a9572000-02-03Henrik Grubbström (Grubba) static void *dlopen(const char *libname, int how)
79f71c1998-07-09Francesco Chemolli { shl_t lib; lib = shl_load(libname, how, 0L); return (void *)lib; }
e1195f1997-03-23Fredrik Hübinette (Hubbe) 
79f71c1998-07-09Francesco Chemolli static char *dlerror(void) { #ifdef HAVE_STRERROR return strerror(errno); #else return ""; /* I hope it's better than null..*/
9649491998-02-27Fredrik Hübinette (Hubbe) #endif
79f71c1998-07-09Francesco 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); }
ecf1552001-09-10Henrik Grubbström (Grubba) #define dlinit() 1
79f71c1998-07-09Francesco Chemolli  #endif /* USE_HPUX_DL */
ecf1552001-09-10Henrik Grubbström (Grubba) #ifdef USE_DYLD #include <mach-o/dyld.h> #define RTLD_NOW NSLINKMODULE_OPTION_BINDNOW #define dlinit() _dyld_present()
fac0412004-03-21Henrik Grubbström (Grubba) struct pike_dl_handle { NSObjectFileImage image; NSModule module; }; static void *dlclose(void *handle_) { struct pike_dl_handle *handle = handle_; if (handle) { if (handle->module) NSUnLinkModule(handle->module, NSUNLINKMODULE_OPTION_NONE); handle->module = NULL; if (handle->image) NSDestroyObjectFileImage(handle->image); handle->image = NULL; free(handle); } return NULL; } static char *pike_dl_error = NULL;
ecf1552001-09-10Henrik Grubbström (Grubba) static void *dlopen(const char *module_name, int how) {
fac0412004-03-21Henrik Grubbström (Grubba)  struct pike_dl_handle *handle = malloc(sizeof(struct pike_dl_handle));
ecf1552001-09-10Henrik Grubbström (Grubba)  NSObjectFileImageReturnCode code = 0;
fac0412004-03-21Henrik Grubbström (Grubba)  pike_dl_error = NULL; if (!handle) { pike_dl_error = "Out of memory."; return NULL; } handle->image = NULL; handle->module = NULL;
ecf1552001-09-10Henrik Grubbström (Grubba) 
3341932004-03-21Henrik Grubbström (Grubba)  /* FIXME: Should be fixed to detect if the module already is loaded. */
fac0412004-03-21Henrik Grubbström (Grubba)  if ((code = NSCreateObjectFileImageFromFile(module_name, &handle->image)) !=
ecf1552001-09-10Henrik Grubbström (Grubba)  NSObjectFileImageSuccess) {
fac0412004-03-21Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG
ecf1552001-09-10Henrik Grubbström (Grubba)  fprintf(stderr, "NSCreateObjectFileImageFromFile(\"%s\") failed with %d\n", module_name, code);
fac0412004-03-21Henrik Grubbström (Grubba) #endif /* PIKE_DEBUG */ pike_dl_error = "NSCreateObjectFileImageFromFile() failed."; dlclose(handle);
ecf1552001-09-10Henrik Grubbström (Grubba)  return NULL; }
3341932004-03-21Henrik Grubbström (Grubba) 
fac0412004-03-21Henrik Grubbström (Grubba)  handle->module = NSLinkModule(handle->image, module_name, how | NSLINKMODULE_OPTION_RETURN_ON_ERROR | NSLINKMODULE_OPTION_PRIVATE); if (!handle->module) { dlclose(handle); return NULL; } return handle; }
3341932004-03-21Henrik Grubbström (Grubba) 
fac0412004-03-21Henrik Grubbström (Grubba) static void *dlsym(void *handle, char *function) { NSSymbol symbol = NSLookupSymbolInModule(((struct pike_dl_handle *)handle)->module, function); return symbol?NSAddressOfSymbol(symbol):NULL;
ecf1552001-09-10Henrik Grubbström (Grubba) }
fac0412004-03-21Henrik Grubbström (Grubba) static const char *dlerror(void)
ecf1552001-09-10Henrik Grubbström (Grubba) { NSLinkEditErrors class = 0; int error_number = 0;
fac0412004-03-21Henrik Grubbström (Grubba)  const char *file_name = NULL; const char *error_string = NULL;
ecf1552001-09-10Henrik Grubbström (Grubba) 
fac0412004-03-21Henrik Grubbström (Grubba)  if (pike_dl_error) return pike_dl_error;
ecf1552001-09-10Henrik Grubbström (Grubba) 
fac0412004-03-21Henrik Grubbström (Grubba)  NSLinkEditError(&class, &error_number, &file_name, &error_string); return error_string;
ecf1552001-09-10Henrik Grubbström (Grubba) } #endif /* USE_DYLD */
9649491998-02-27Fredrik Hübinette (Hubbe)  #ifndef EMULATE_DLOPEN
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) 
ecf1552001-09-10Henrik Grubbström (Grubba) #define dlinit() 1
79f71c1998-07-09Francesco Chemolli #endif /* !EMULATE_DLOPEN */
7860031997-01-22Bernhard Fastenrath 
58dd661998-09-18Fredrik Hübinette (Hubbe) #endif /* HAVE_SOME_DLOPEN */
e1195f1997-03-23Fredrik Hübinette (Hubbe) #ifndef RTLD_NOW #define RTLD_NOW 0 #endif
5aeade1999-02-01Per Hedbor #ifndef RTLD_LAZY #define RTLD_LAZY 0 #endif #ifndef RTLD_GLOBAL #define RTLD_GLOBAL 0 #endif
56f4f42001-09-18Fredrik Hübinette (Hubbe) #ifndef NO_PIKE_GUTS
e1195f1997-03-23Fredrik Hübinette (Hubbe) 
6d76cf2003-12-10Henrik Grubbström (Grubba) #if defined(HAVE_DLOPEN) || defined(USE_DLD) || defined(USE_HPUX_DL) || \ defined(USE_LOADLIBRARY) || defined(USE_DYLD)
e00cc82000-09-29Martin Stjernholm #define USE_DYNAMIC_MODULES #endif #ifdef USE_DYNAMIC_MODULES
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;
2dcd142004-03-21Henrik Grubbström (Grubba)  struct pike_string *name;
63be682002-03-10Martin Stjernholm  struct program *module_prog;
6cf83a1997-02-06Fredrik Hübinette (Hubbe)  modfun init, exit;
368fe71997-01-26Fredrik Hübinette (Hubbe) }; struct module_list *dynamic_module_list = 0;
418a371999-04-25Henrik Grubbström (Grubba) #ifdef NO_CAST_TO_FUN /* Function pointers can't be casted to scalar pointers according to * ISO-C (probably to support true Harward achitecture machines). */ 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 */
8853882008-04-26Henrik Grubbström (Grubba) static void cleanup_compilation(void *ignored)
fc29cf2002-01-30Marcus Comstedt {
4a36b22003-06-06Henrik Grubbström (Grubba)  struct program *p = end_program(); if (p) { free_program(p); }
fc29cf2002-01-30Marcus Comstedt }
63be682002-03-10Martin Stjernholm /*! @decl program load_module(string module_name)
7c0df72001-02-06Henrik Grubbström (Grubba)  *! *! Load a binary module. *! *! This function loads a module written in C or some other language *! into Pike. The module is initialized and any programs or constants *! defined will immediately be available. *!
cbe8c92003-04-07Martin Nilsson  *! When a module is loaded the C function @tt{pike_module_init()@} will
7c0df72001-02-06Henrik Grubbström (Grubba)  *! be called to initialize it. When Pike exits @tt{pike_module_exit()@} *! will be called. These two functions @b{must@} be available in the module. *! *! @note *! The current working directory is normally not searched for
cbe8c92003-04-07Martin Nilsson  *! dynamic modules. Please use @expr{"./name.so"@} instead of just *! @expr{"name.so"@} to load modules from the current directory.
7c0df72001-02-06Henrik Grubbström (Grubba)  */
368fe71997-01-26Fredrik Hübinette (Hubbe) void f_load_module(INT32 args) {
9552622001-09-10Fredrik Hübinette (Hubbe)  extern int global_callable_flags;
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;
2dcd142004-03-21Henrik Grubbström (Grubba)  struct pike_string *module_name;
368fe71997-01-26Fredrik Hübinette (Hubbe) 
fc29cf2002-01-30Marcus Comstedt  ONERROR err;
2dcd142004-03-21Henrik Grubbström (Grubba)  module_name = Pike_sp[-args].u.string; if((Pike_sp[-args].type != T_STRING) || (module_name->size_shift) ||
2dd2ee2005-11-12Martin Nilsson  string_has_null(module_name)) {
b2d3e42000-12-01Fredrik Hübinette (Hubbe)  Pike_error("Bad argument 1 to load_module()\n");
2dcd142004-03-21Henrik Grubbström (Grubba)  }
368fe71997-01-26Fredrik Hübinette (Hubbe) 
2dcd142004-03-21Henrik Grubbström (Grubba)  { struct module_list *mp; for (mp = dynamic_module_list; mp; mp = mp->next) if (mp->name == module_name && mp->module_prog) { pop_n_elems(args); ref_push_program(mp->module_prog); return; } }
368fe71997-01-26Fredrik Hübinette (Hubbe) 
0819302000-02-17Fredrik Hübinette (Hubbe)  /* Removing RTLD_GLOBAL breaks some PiGTK themes - Hubbe */
8bff492000-09-26Fredrik Hübinette (Hubbe)  /* Using RTLD_LAZY is faster, but makes it impossible to * detect linking problems at runtime.. */
2dcd142004-03-21Henrik Grubbström (Grubba)  module=dlopen(module_name->str,
56688c2002-05-10Per Hedbor  RTLD_NOW /*|RTLD_GLOBAL*/ );
ef78b01997-11-03Henrik Grubbström (Grubba) 
368fe71997-01-26Fredrik Hübinette (Hubbe)  if(!module) {
df019f2004-04-18Martin Stjernholm  struct object *err_obj = low_clone (module_load_error_program); #define LOADERR_STRUCT(OBJ) \ ((struct module_load_error_struct *) (err_obj->storage + module_load_error_offset))
20b5222004-03-22Martin Stjernholm 
466a321997-09-07Henrik Grubbström (Grubba)  const char *err = dlerror();
20b5222004-03-22Martin Stjernholm  if (err) { if (err[strlen (err) - 1] == '\n') push_string (make_shared_binary_string (err, strlen (err) - 1)); else push_text (err); } else push_constant_text ("Unknown reason");
df019f2004-04-18Martin Stjernholm  add_ref (LOADERR_STRUCT (err_obj)->path = Pike_sp[-args - 1].u.string); add_ref (LOADERR_STRUCT (err_obj)->reason = Pike_sp[-1].u.string);
20b5222004-03-22Martin Stjernholm 
9b150a2002-05-11Martin Nilsson  if (Pike_sp[-args].u.string->len < 1024) {
20b5222004-03-22Martin Stjernholm  throw_error_object (err_obj, "load_module", Pike_sp - args - 1, args, "load_module(\"%s\") failed: %s\n", module_name->str, Pike_sp[-1].u.string->str);
14160c1998-05-15Henrik Grubbström (Grubba)  } else {
20b5222004-03-22Martin Stjernholm  throw_error_object (err_obj, "load_module", Pike_sp - args - 1, args, "load_module() failed: %s\n", Pike_sp[-1].u.string->str);
14160c1998-05-15Henrik Grubbström (Grubba)  }
368fe71997-01-26Fredrik Hübinette (Hubbe)  }
2dcd142004-03-21Henrik Grubbström (Grubba) #ifdef PIKE_DEBUG
63be682002-03-10Martin Stjernholm  { struct module_list *mp; for (mp = dynamic_module_list; mp; mp = mp->next) if (mp->module == module && mp->module_prog) {
2dcd142004-03-21Henrik Grubbström (Grubba)  fprintf(stderr, "load_module(): Module loaded twice:\n" "Old name: %s\n" "New name: %s\n", mp->name->str, module_name->str);
384c472002-05-01Martin Stjernholm  pop_n_elems(args);
63be682002-03-10Martin Stjernholm  ref_push_program(mp->module_prog); return; } }
2dcd142004-03-21Henrik Grubbström (Grubba) #endif /* PIKE_DEBUG */
63be682002-03-10Martin Stjernholm 
418a371999-04-25Henrik Grubbström (Grubba)  init = CAST_TO_FUN(dlsym(module, "pike_module_init"));
fb84a71997-03-04Henrik Grubbström (Grubba)  if (!init) {
418a371999-04-25Henrik Grubbström (Grubba)  init = CAST_TO_FUN(dlsym(module, "_pike_module_init"));
faf4922004-04-14Martin Stjernholm  if (!init) { dlclose(module);
9606eb2004-11-12Henrik Grubbström (Grubba)  Pike_error("pike_module_init missing in dynamic module \"%S\".\n", module_name);
faf4922004-04-14Martin Stjernholm  }
fb84a71997-03-04Henrik Grubbström (Grubba)  }
faf4922004-04-14Martin Stjernholm 
418a371999-04-25Henrik Grubbström (Grubba)  exit = CAST_TO_FUN(dlsym(module, "pike_module_exit"));
fb84a71997-03-04Henrik Grubbström (Grubba)  if (!exit) {
418a371999-04-25Henrik Grubbström (Grubba)  exit = CAST_TO_FUN(dlsym(module, "_pike_module_exit"));
faf4922004-04-14Martin Stjernholm  if (!exit) { dlclose(module);
9606eb2004-11-12Henrik Grubbström (Grubba)  Pike_error("pike_module_exit missing in dynamic module \"%S\".\n", module_name);
14160c1998-05-15Henrik Grubbström (Grubba)  }
368fe71997-01-26Fredrik Hübinette (Hubbe)  }
faf4922004-04-14Martin Stjernholm 
458a712002-10-30Henrik Grubbström (Grubba) #if defined(__NT__) && defined(_M_IA64) { fprintf(stderr, "pike_module_init: 0x%p\n" " func: 0x%p\n" " gp: 0x%p\n", init, ((void **)init)[0], ((void **)init)[1]); fprintf(stderr, "pike_module_exit: 0x%p\n" " func: 0x%p\n" " gp: 0x%p\n", exit, ((void **)exit)[0], ((void **)exit)[1]); } #endif /* __NT__ && _M_IA64 */
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;
2dcd142004-03-21Henrik Grubbström (Grubba)  copy_shared_string(new_module->name, Pike_sp[-args].u.string);
63be682002-03-10Martin Stjernholm  new_module->module_prog = NULL;
6cf83a1997-02-06Fredrik Hübinette (Hubbe)  new_module->init=init; new_module->exit=exit;
368fe71997-01-26Fredrik Hübinette (Hubbe) 
e021fe2008-04-14Henrik Grubbström (Grubba)  enter_compiler(new_module->name, 1);
368fe71997-01-26Fredrik Hübinette (Hubbe)  start_new_program();
c39e432001-08-02Fredrik Hübinette (Hubbe) 
9552622001-09-10Fredrik Hübinette (Hubbe)  global_callable_flags|=CALLABLE_DYNAMIC;
c39e432001-08-02Fredrik Hübinette (Hubbe) 
044c621999-04-14Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
9b150a2002-05-11Martin Nilsson  { struct svalue *save_sp=Pike_sp;
044c621999-04-14Fredrik Hübinette (Hubbe) #endif
8853882008-04-26Henrik Grubbström (Grubba)  SET_ONERROR(err, cleanup_compilation, NULL);
458a712002-10-30Henrik Grubbström (Grubba) #if defined(__NT__) && defined(_M_IA64) fprintf(stderr, "Calling pike_module_init()...\n"); #endif /* __NT__ && _M_IA64 */
6cf83a1997-02-06Fredrik Hübinette (Hubbe)  (*(modfun)init)();
458a712002-10-30Henrik Grubbström (Grubba) #if defined(__NT__) && defined(_M_IA64) fprintf(stderr, "pike_module_init() done.\n"); #endif /* __NT__ && _M_IA64 */
fc29cf2002-01-30Marcus Comstedt  UNSET_ONERROR(err);
044c621999-04-14Fredrik Hübinette (Hubbe) #ifdef PIKE_DEBUG
9b150a2002-05-11Martin Nilsson  if(Pike_sp != save_sp)
5aad932002-08-15Marcus Comstedt  Pike_fatal("load_module(%s) left %ld droppings on stack!\n",
2dcd142004-03-21Henrik Grubbström (Grubba)  module_name->str, PTRDIFF_T_TO_LONG(Pike_sp - save_sp));
044c621999-04-14Fredrik Hübinette (Hubbe)  } #endif
6cf83a1997-02-06Fredrik Hübinette (Hubbe) 
044c621999-04-14Fredrik Hübinette (Hubbe)  pop_n_elems(args);
4a36b22003-06-06Henrik Grubbström (Grubba)  { struct program *p = end_program();
e021fe2008-04-14Henrik Grubbström (Grubba)  exit_compiler();
4a36b22003-06-06Henrik Grubbström (Grubba)  if (p) {
0bd1472004-04-15Henrik Grubbström (Grubba)  if ( #if 0 p->num_identifier_references #else /* !0 */ 1 #endif /* 0 */ ) {
1cb5d52004-04-14Henrik Grubbström (Grubba)  push_program(p); add_ref(new_module->module_prog = Pike_sp[-1].u.program); } else { /* No identifier references -- Disabled module. */ free_program(p); push_undefined(); }
4a36b22003-06-06Henrik Grubbström (Grubba)  } else { /* Initialization failed. */ new_module->exit(); dlclose(module); dynamic_module_list = new_module->next;
650a972005-10-19Martin Nilsson  free_string(new_module->name);
4a36b22003-06-06Henrik Grubbström (Grubba)  free(new_module);
9606eb2004-11-12Henrik Grubbström (Grubba)  Pike_error("Failed to initialize dynamic module \"%S\".\n", module_name);
4a36b22003-06-06Henrik Grubbström (Grubba)  } }
368fe71997-01-26Fredrik Hübinette (Hubbe) }
e00cc82000-09-29Martin Stjernholm #endif /* USE_DYNAMIC_MODULES */
368fe71997-01-26Fredrik Hübinette (Hubbe) 
e1195f1997-03-23Fredrik Hübinette (Hubbe) void init_dynamic_load(void)
368fe71997-01-26Fredrik Hübinette (Hubbe) {
e00cc82000-09-29Martin Stjernholm #ifdef USE_DYNAMIC_MODULES
ecf1552001-09-10Henrik Grubbström (Grubba)  if (dlinit()) {
45ee5d1999-02-10Fredrik Hübinette (Hubbe) 
ecf1552001-09-10Henrik Grubbström (Grubba)  /* function(string:program) */
1f21332000-07-28Fredrik Hübinette (Hubbe) 
ecf1552001-09-10Henrik Grubbström (Grubba)  ADD_EFUN("load_module", f_load_module, tFunc(tStr,tPrg(tObj)), OPT_EXTERNAL_DEPEND); }
368fe71997-01-26Fredrik Hübinette (Hubbe) #endif }
da667d2000-09-28Henrik Grubbström (Grubba) /* Call the pike_module_exit() callbacks for the dynamic modules. */
be478c1997-08-30Henrik Grubbström (Grubba) void exit_dynamic_load(void)
368fe71997-01-26Fredrik Hübinette (Hubbe) {
e00cc82000-09-29Martin Stjernholm #ifdef USE_DYNAMIC_MODULES
766bc82004-10-16Marcus Agehall  struct module_list * volatile tmp;
fc29cf2002-01-30Marcus Comstedt  JMP_BUF recovery;
e00cc82000-09-29Martin Stjernholm  for (tmp = dynamic_module_list; tmp; tmp = tmp->next)
fc29cf2002-01-30Marcus Comstedt  { if(SETJMP(recovery)) call_handle_error(); else (*tmp->exit)();
63be682002-03-10Martin Stjernholm  UNSETJMP(recovery); free_program(tmp->module_prog); tmp->module_prog = NULL;
0dd0572004-03-21Henrik Grubbström (Grubba)  free_string(tmp->name); tmp->name = NULL;
fc29cf2002-01-30Marcus Comstedt  }
da667d2000-09-28Henrik Grubbström (Grubba) #endif } /* Unload all the dynamically loaded modules. */ void free_dynamic_load(void) {
e00cc82000-09-29Martin Stjernholm #ifdef USE_DYNAMIC_MODULES
da667d2000-09-28Henrik Grubbström (Grubba)  while(dynamic_module_list) { struct module_list *tmp=dynamic_module_list; dynamic_module_list=tmp->next;
3c0c281998-01-26Fredrik Hübinette (Hubbe) #ifndef DEBUG_MALLOC
368fe71997-01-26Fredrik Hübinette (Hubbe)  dlclose(tmp->module);
3c0c281998-01-26Fredrik Hübinette (Hubbe) #endif
b0234c2003-04-02Martin Stjernholm #ifdef PIKE_DEBUG if (tmp->module_prog)
0dd0572004-03-21Henrik Grubbström (Grubba)  Pike_fatal ("There's still a program for a dynamic module.\n");
b0234c2003-04-02Martin Stjernholm #endif
368fe71997-01-26Fredrik Hübinette (Hubbe)  free((char *)tmp); }
7860031997-01-22Bernhard Fastenrath #endif
368fe71997-01-26Fredrik Hübinette (Hubbe) }
56f4f42001-09-18Fredrik Hübinette (Hubbe) #endif /* NO_PIKE_GUTS */ #ifdef CREATE_MAIN
e1195f1997-03-23Fredrik Hübinette (Hubbe) #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;
618bdd2001-11-26Henrik Grubbström (Grubba)  if (!dlinit()) { fprintf(stderr, "dlinit() failed.\n"); exit(1); }
e1195f1997-03-23Fredrik Hübinette (Hubbe)  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) }
56f4f42001-09-18Fredrik Hübinette (Hubbe) #endif /* CREATE_MAIN */