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