From e1195f5f775a8c90a0f18ac868a0274be2728932 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20H=C3=BCbinette=20=28Hubbe=29?= <hubbe@hubbe.net> Date: Sun, 23 Mar 1997 16:44:37 -0800 Subject: [PATCH] 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 --- src/ChangeLog | 1 + src/configure.in | 43 +++++-- src/dynamic_load.c | 313 ++++++++++++--------------------------------- src/main.c | 5 +- 4 files changed, 120 insertions(+), 242 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index 9c1a887722..b185753f50 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,5 +1,6 @@ Sun Mar 23 14:09:18 1997 Fredrik Hubinette <hubbe@cytocin.hubbe.net> + * configure.in: added test for dynamic loading of modules * program.c (get_storage): new function Mon Mar 17 14:14:34 1997 Fredrik Hubinette <hubbe@cytocin.hubbe.net> diff --git a/src/configure.in b/src/configure.in index c2b45d5fff..fe3d1e0dee 100644 --- a/src/configure.in +++ b/src/configure.in @@ -1,4 +1,4 @@ -AC_REVISION("$Id: configure.in,v 1.63 1997/03/17 22:42:47 hubbe Exp $") +AC_REVISION("$Id: configure.in,v 1.64 1997/03/24 00:44:36 hubbe Exp $") AC_INIT(interpret.c) AC_CONFIG_HEADER(machine.h) @@ -1281,7 +1281,7 @@ AC_SUBST(CCSHARED) AC_SUBST(LINKFORSHARED) # SO is the extension of shared libraries -# -- usually .so, .sl on HP-UX +# -- usually so, sl on HP-UX AC_MSG_CHECKING(SO) if test -z "$SO" then @@ -1330,7 +1330,7 @@ fi AC_MSG_RESULT($CCSHARED) # LINKFORSHARED are the flags passed to the $(CC) command that links -# the python executable -- this is only needed for a few systems +# the pike executable -- this is only needed for a few systems AC_MSG_CHECKING(LINKFORSHARED) if test -z "$LINKFORSHARED" then @@ -1356,14 +1356,35 @@ AC_MSG_RESULT($LINKFORSHARED) ############################################################################# -LIBDIR=`(cd $srcdir/../lib ; pwd)` -BINDIR=`(cd $srcdir/../bin ; pwd)` -DOCDIR=`(cd $srcdir/../doc ; pwd)` -BUILDDIR=`pwd` -AC_SUBST(LIBDIR) -AC_SUBST(BINDIR) -AC_SUBST(BUILDDIR) -AC_SUBST(DOCDIR) +cat >conftest.c <<EOF +void testfunc(void) { exit(0); } +EOF + +$CC -c $CFLAGS $CCSHARED conftest.c -o conftest.o +$BINDIR/smartlink $LDSHARED $LDFLAGS conftest.o -o conftest.$SO + +mv conftest.$SO myconftest.so + +AC_MSG_CHECKING(if dynamic loading works) +AC_CACHE_VAL(pike_cv_sys_dynamic_loading, +[ + OLD_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $LINKFORSHARED" + AC_TRY_RUN([ +#define TESTING +#include "$srcdir/dynamic_load.c" +], pike_cv_sys_dynamic_loading=yes, pike_cv_sys_dynamic_loading=no) + CFLAGS="$OLD_CFLAGS" +]) +AC_MSG_RESULT($pike_cv_sys_dynamic_loading) + +if test x$pike_cv_sys_dynamic_loading = xno ; then + with_dynamic_modules=no +fi + +rm myconftest.so + +############################################################################# export LDFLAGS CPPFLAGS LIBS diff --git a/src/dynamic_load.c b/src/dynamic_load.c index 8a793fe635..adc1e32199 100644 --- a/src/dynamic_load.c +++ b/src/dynamic_load.c @@ -1,4 +1,12 @@ -#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,25 +16,68 @@ #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 { @@ -49,30 +100,15 @@ void f_load_module(INT32 args) 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,19 +118,9 @@ void f_load_module(INT32 args) 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,12 +142,9 @@ void f_load_module(INT32 args) #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,204 +159,34 @@ void exit_dynamic_load() 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 - -#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" +#else /* TESTING */ +#include <stdio.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) -{ -#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 */ + void *module,*fun; + dlinit(); + module=dlopen("./myconftest.so",RTLD_NOW); + if(!module) { - 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)); - } - 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()); + fprintf(stderr,"Failed to link myconftest.so: %s\n",dlerror()); + exit(1); } -#endif - pop_n_elems(args); - push_int(res); -} - - -#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:int)",OPT_SIDE_EFFECT); -#endif -} - -void exit_dynamic_load() -{ -#if defined(HAVE_DLOPEN) || defined(USE_DLD) - while(dynamic_module_list) + fun=dlsym(module,"testfunc"); + if(!fun) fun=dlsym(module,"_testfunc"); + if(!fun) { - 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); - } -#endif - free((char *)tmp); + fprintf(stderr,"Failed to find function testfunc: %s\n",dlerror()); + exit(1); } -#endif + ((void (*)(void))fun)(); + exit(1); } - - #endif diff --git a/src/main.c b/src/main.c index 171412688f..790a750801 100644 --- a/src/main.c +++ b/src/main.c @@ -4,7 +4,7 @@ ||| See the files COPYING and DISCLAIMER for more information. \*/ #include "global.h" -RCSID("$Id: main.c,v 1.19 1997/03/17 03:04:40 hubbe Exp $"); +RCSID("$Id: main.c,v 1.20 1997/03/24 00:44:37 hubbe Exp $"); #include "types.h" #include "backend.h" #include "module.h" @@ -33,6 +33,7 @@ RCSID("$Id: main.c,v 1.19 1997/03/17 03:04:40 hubbe Exp $"); char *master_file; +char **ARGV; int d_flag=0; int c_flag=0; @@ -58,6 +59,8 @@ void main(int argc, char **argv, char **env) char *p; struct array *a; + ARGV=argv; + #ifdef HAVE_SETLOCALE #ifdef LC_NUMERIC setlocale(LC_NUMERIC, "C"); -- GitLab