pike.git / src / dynamic_load.c

version» Context lines:

pike.git/src/dynamic_load.c:8:   #define NO_PIKE_INCLUDES   #define CREATE_MAIN   #define NO_PIKE_GUTS   #endif      #ifndef NO_PIKE_INCLUDES   # include "global.h"   # include "interpret.h"   # include "constants.h"   # include "pike_error.h" - # include "module.h" + # include "pike_compiler.h"   # include "stralloc.h"   # include "pike_macros.h"   # include "main.h"   # include "constants.h"   # include "lex.h"   # include "object.h" -  + # include "cyclic.h"      #else /* TESTING */      #include <stdio.h> -  + #include <string.h>      #endif /* !TESTING */    - #ifdef HAVE_ERRNO_H +    #include <errno.h> - #endif /* HAVE_ERRNO_H */ - #ifdef HAVE_STRING_H - #include <string.h> - #endif /* HAVE_STRING_H */ +     - #if !defined(HAVE_DLOPEN) + #if !defined(HAVE_DLOPEN) || defined(USE_SEMIDYNAMIC_MODULES)    - #if defined(HAVE_DLD_LINK) && defined(HAVE_DLD_GET_FUNC) + #ifdef USE_SEMIDYNAMIC_MODULES + #undef HAVE_DLOPEN + #define USE_STATIC_MODULES + #define HAVE_SOME_DLOPEN + #define EMULATE_DLOPEN + #define USE_DYNAMIC_MODULES + #elif defined(HAVE_DLD_LINK) && defined(HAVE_DLD_GET_FUNC)   #define USE_DLD   #define HAVE_SOME_DLOPEN   #define EMULATE_DLOPEN - #else - #if defined(HAVE_SHL_LOAD) && defined(HAVE_DL_H) + #elif defined(HAVE_SHL_LOAD) && defined(HAVE_DL_H)   #define USE_HPUX_DL   #define HAVE_SOME_DLOPEN   #define EMULATE_DLOPEN - #else -  - #ifdef USE_DLL - #if defined(HAVE_LOADLIBRARY) && defined(HAVE_FREELIBRARY) && \ + #elif defined(USE_DLL) && \ +  defined(HAVE_LOADLIBRARY) && defined(HAVE_FREELIBRARY) && \    defined(HAVE_GETPROCADDRESS) && defined(HAVE_WINBASE_H)   #define USE_LOADLIBRARY   #define HAVE_SOME_DLOPEN   #define EMULATE_DLOPEN - #endif - #endif -  - #ifdef HAVE_MACH_O_DYLD_H + #elif defined(HAVE_MACH_O_DYLD_H)   /* MacOS X... */   #define USE_DYLD   #define HAVE_SOME_DLOPEN   #define EMULATE_DLOPEN - #endif /* HAVE_MACH_O_DYLD_H */ -  +    #endif - #endif +    #else -  + /* HAVE_DLOPEN */   #define HAVE_SOME_DLOPEN   #endif         #ifdef HAVE_SOME_DLOPEN      typedef void (*modfun)(void);    - #ifdef USE_LOADLIBRARY + #ifdef USE_STATIC_MODULES +  + static void *dlopen(const char *foo, int how) + { +  struct pike_string *s = low_read_file(foo); +  char *name, *end; +  void *res; +  +  if (!s) return NULL; +  if (strncmp(s->str, "PMODULE=\"", 9)) { +  free_string(s); +  return NULL; +  } +  name = s->str + 9; +  if (!(end = strchr(name, '\"'))) { +  free_string(s); +  return NULL; +  } +  +  res = find_semidynamic_module(name, end - name); +  free_string(s); +  return res; + } +  + static char *dlerror(void) + { +  return "Invalid dynamic module."; + } +  + static void *dlsym(void *module, char *function) + { +  if (!strcmp(function, "pike_module_init")) +  return get_semidynamic_init_fun(module); +  if (!strcmp(function, "pike_module_exit")) +  return get_semidynamic_exit_fun(module); +  return NULL; + } +  + static int dlinit(void) + { +  return 1; + } +  + static void dlclose(void *module) + { + } +  + #elif defined(USE_LOADLIBRARY)   #include <windows.h>      static TCHAR *convert_string(const char *str, ptrdiff_t len)   {    ptrdiff_t e; -  TCHAR *ret=(TCHAR *)xalloc((len+1) * sizeof(TCHAR)); +  TCHAR *ret=xalloc((len+1) * sizeof(TCHAR));    for(e=0;e<len;e++) ret[e]=EXTRACT_UCHAR(str+e);    ret[e]=0;    return ret;   }      static void *dlopen(const char *foo, int how)   {    TCHAR *tmp;    HINSTANCE ret;    tmp=convert_string(foo, strlen(foo));    ret=LoadLibrary(tmp); -  free((char *)tmp); +  free(tmp);    return (void *)ret;   }      static char * dlerror(void)   {    static char buffer[200];    int err = GetLastError();    switch(err) {    case ERROR_MOD_NOT_FOUND:    return "The specified module could not be found.";
pike.git/src/dynamic_load.c:169:    return 1;   }      #endif /* USE_DLD */         #ifdef USE_HPUX_DL      #include <dl.h>    - #if defined(BIND_VERBOSE) + #ifdef BIND_VERBOSE   #define RTLD_NOW BIND_IMMEDIATE | BIND_VERBOSE   #else   #define RTLD_NOW BIND_IMMEDIATE   #endif /* BIND_VERBOSE */      extern int errno;      static void *dlopen(const char *libname, int how)   {    shl_t lib;       lib = shl_load(libname, how, 0L);       return (void *)lib;   }      static char *dlerror(void)   { - #ifdef HAVE_STRERROR +     return strerror(errno); - #else -  return ""; /* I hope it's better than null..*/ - #endif +    }      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)
pike.git/src/dynamic_load.c:265:    return NULL;    }       handle->image = NULL;    handle->module = NULL;       /* FIXME: Should be fixed to detect if the module already is loaded. */    if ((code = NSCreateObjectFileImageFromFile(module_name,    &handle->image)) !=    NSObjectFileImageSuccess) { - #ifdef PIKE_DEBUG -  fprintf(stderr, "NSCreateObjectFileImageFromFile(\"%s\") failed with %d\n", +  DWERR("NSCreateObjectFileImageFromFile(\"%s\") failed with %d\n",    module_name, code); - #endif /* PIKE_DEBUG */ +     pike_dl_error = "NSCreateObjectFileImageFromFile() failed.";    dlclose(handle);    return NULL;    }       handle->module = NSLinkModule(handle->image, module_name,    how | NSLINKMODULE_OPTION_RETURN_ON_ERROR |    NSLINKMODULE_OPTION_PRIVATE);    if (!handle->module) {    dlclose(handle);
pike.git/src/dynamic_load.c:398:    *!    *! @note    *! The current working directory is normally not searched for    *! dynamic modules. Please use @expr{"./name.so"@} instead of just    *! @expr{"name.so"@} to load modules from the current directory.    */   void f_load_module(INT32 args)   {    extern int global_callable_flags;    -  void *module; +  void *module = NULL;    modfun init, exit;    struct module_list *new_module;    struct pike_string *module_name;       ONERROR err; -  +  DECLARE_CYCLIC();       module_name = Pike_sp[-args].u.string;       if((TYPEOF(Pike_sp[-args]) != T_STRING) ||    (module_name->size_shift) ||    string_has_null(module_name)) {    Pike_error("Bad argument 1 to load_module()\n");    }       {    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;    }    }    -  +  if (!BEGIN_CYCLIC(module_name, 0)) { +  SET_CYCLIC_RET(1); +     /* Removing RTLD_GLOBAL breaks some PiGTK themes - Hubbe */    /* Using RTLD_LAZY is faster, but makes it impossible to    * detect linking problems at runtime..    */    module=dlopen(module_name->str,    RTLD_NOW /*|RTLD_GLOBAL*/ ); -  +  }       if(!module)    {    struct object *err_obj = fast_clone_object(module_load_error_program);   #define LOADERR_STRUCT(OBJ) \    ((struct module_load_error_struct *) (err_obj->storage + module_load_error_offset))       const char *err = dlerror(); -  +  struct pike_string *str;    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"); +  push_static_text ("Unknown reason");       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); +  add_ref (LOADERR_STRUCT (err_obj)->reason = str = Pike_sp[-1].u.string); +  pop_stack();    -  if (Pike_sp[-args].u.string->len < 1024) { -  throw_error_object (err_obj, "load_module", Pike_sp - args - 1, args, +  if (str->len < 1024) { +  throw_error_object (err_obj, "load_module", args,    "load_module(\"%s\") failed: %s\n", -  module_name->str, Pike_sp[-1].u.string->str); +  module_name->str, str->str);    } else { -  throw_error_object (err_obj, "load_module", Pike_sp - args - 1, args, -  "load_module() failed: %s\n", -  Pike_sp[-1].u.string->str); +  throw_error_object (err_obj, "load_module", args, +  "load_module(\"%s\") failed.\n", +  module_name->str);    }    }      #ifdef PIKE_DEBUG    {    struct module_list *mp;    for (mp = dynamic_module_list; mp; mp = mp->next)    if (mp->module == module && mp->module_prog) {    fprintf(stderr, "load_module(): Module loaded twice:\n"    "Old name: %s\n"    "New name: %s\n",    mp->name->str, module_name->str);    pop_n_elems(args);    ref_push_program(mp->module_prog); -  +  END_CYCLIC();    return;    }    }   #endif /* PIKE_DEBUG */       init = CAST_TO_FUN(dlsym(module, "pike_module_init"));    if (!init) {    init = CAST_TO_FUN(dlsym(module, "_pike_module_init"));    if (!init) {    dlclose(module);
pike.git/src/dynamic_load.c:496:    exit = CAST_TO_FUN(dlsym(module, "pike_module_exit"));    if (!exit) {    exit = CAST_TO_FUN(dlsym(module, "_pike_module_exit"));    if (!exit) {    dlclose(module);    Pike_error("pike_module_exit missing in dynamic module \"%S\".\n",    module_name);    }    }    - #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 */ -  +     new_module=ALLOC_STRUCT(module_list);    new_module->next=dynamic_module_list;    dynamic_module_list=new_module;    new_module->module=module;    copy_shared_string(new_module->name, Pike_sp[-args].u.string);    new_module->module_prog = NULL;    new_module->init=init;    new_module->exit=exit;       enter_compiler(new_module->name, 1);       start_new_program();       global_callable_flags|=CALLABLE_DYNAMIC;      #ifdef PIKE_DEBUG    { struct svalue *save_sp=Pike_sp;   #endif    SET_ONERROR(err, cleanup_compilation, NULL); - #if defined(__NT__) && defined(_M_IA64) -  fprintf(stderr, "Calling pike_module_init()...\n"); - #endif /* __NT__ && _M_IA64 */ +     (*(modfun)init)(); - #if defined(__NT__) && defined(_M_IA64) -  fprintf(stderr, "pike_module_init() done.\n"); - #endif /* __NT__ && _M_IA64 */ +     UNSET_ONERROR(err);   #ifdef PIKE_DEBUG    if(Pike_sp != save_sp)    Pike_fatal("pike_module_init in %s left "    "%"PRINTPTRDIFFT"d droppings on stack.\n",    module_name->str, Pike_sp - save_sp);    }   #endif       pop_n_elems(args);
pike.git/src/dynamic_load.c:580: Inside #if defined(PIKE_DEBUG)
   if(Pike_sp != save_sp)    Pike_fatal("pike_module_exit in %s left "    "%"PRINTPTRDIFFT"d droppings on stack.\n",    module_name->str, Pike_sp - save_sp);   #endif       dlclose(module);    dynamic_module_list = new_module->next;    free_string(new_module->name);    free(new_module); +  END_CYCLIC();    Pike_error("Failed to initialize dynamic module \"%S\".\n",    module_name);    }    } -  +  END_CYCLIC();   }      #endif /* USE_DYNAMIC_MODULES */         void init_dynamic_load(void)   {   #ifdef USE_DYNAMIC_MODULES    if (dlinit()) {   
pike.git/src/dynamic_load.c:651: Inside #if defined(USE_DYNAMIC_MODULES)
   {    struct module_list *tmp=dynamic_module_list;    dynamic_module_list=tmp->next;   #ifndef DEBUG_MALLOC    dlclose(tmp->module);   #endif   #ifdef PIKE_DEBUG    if (tmp->module_prog)    Pike_fatal ("There's still a program for a dynamic module.\n");   #endif -  free((char *)tmp); +  free(tmp);    }   #endif   }         #endif /* NO_PIKE_GUTS */      #ifdef CREATE_MAIN   #include <stdio.h>