* procs.h: Doc fix.
[bpt/guile.git] / libguile / dynl.c
index 4dfe8ea..31d9404 100644 (file)
@@ -1,6 +1,6 @@
 /* dynl.c - dynamic linking
  *
- * Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+ * Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
  * 
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -14,7 +14,8 @@
  * 
  * You should have received a copy of the GNU General Public License
  * along with this software; see the file COPYING.  If not, write to
- * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307 USA
  *
  * As a special exception, the Free Software Foundation gives permission
  * for additional uses of the text contained in its release of GUILE.
  *
  * If you write modifications of your own for GUILE, it is your choice
  * whether to permit this exception to apply to your modifications.
- * If you do not wish that, delete this exception notice.  
- */
+ * If you do not wish that, delete this exception notice.  */
 
 /* "dynl.c" dynamically link&load object files.
    Author: Aubrey Jaffer
    Modified for libguile by Marius Vollmer */
 
+#if 0 /* Disabled until we know for sure that it isn't needed */
 /* XXX - This is only here to drag in a definition of __eprintf. This
    is needed for proper operation of dynamic linking. The real
    solution would probably be a shared libgcc. */
@@ -57,14 +58,14 @@ maybe_drag_in_eprintf ()
 {
   assert (!maybe_drag_in_eprintf);
 }
+#endif
 
+#include <stdio.h>
 #include "_scm.h"
 #include "dynl.h"
 #include "genio.h"
 #include "smob.h"
 
-#ifdef DYNAMIC_LINKING
-
 /* Converting a list of SCM strings into a argv-style array.  You must
    have ints disabled for the whole lifetime of the created argv (from
    before MAKE_ARGV_FROM_STRINGLIST until after
@@ -74,13 +75,13 @@ maybe_drag_in_eprintf ()
    This code probably belongs into strings.c */
 
 static char **scm_make_argv_from_stringlist SCM_P ((SCM args, int *argcp,
-                                                   char *subr, int argn));
+                                                   const char *subr, int argn));
 
 static char **
 scm_make_argv_from_stringlist (args, argcp, subr, argn)
      SCM args;
      int *argcp;
-     char *subr;
+     const char *subr;
      int argn;
 {
     char **argv;
@@ -115,20 +116,20 @@ scm_must_free_argv(argv)
      char **argv;
 {
     char **av = argv;
-    while(!(*av))
-       free(*(av++));
+    while (*av)
+      free(*(av++));
     free(argv);
 }
 
 /* Coerce an arbitrary readonly-string into a zero-terminated string.
  */
 
-static SCM scm_coerce_rostring SCM_P ((SCM rostr, char *subr, int argn));
+static SCM scm_coerce_rostring SCM_P ((SCM rostr, const char *subr, int argn));
 
 static SCM
 scm_coerce_rostring (rostr, subr, argn)
      SCM rostr;
-     char *subr;
+     const char *subr;
      int argn;
 {
     SCM_ASSERT (SCM_NIMP (rostr) && SCM_ROSTRINGP (rostr), rostr, argn, subr);
@@ -169,8 +170,12 @@ scm_register_module_xxx (module_name, init_func)
        }
 
     md = (struct moddata *)malloc (sizeof (struct moddata));
-    if (md == NULL)
+    if (md == NULL) {
+       fprintf (stderr,
+                "guile: can't register module (%s): not enough memory",
+                module_name);
        return;
+    }
 
     md->module_name = module_name;
     md->init_func = init_func;
@@ -215,25 +220,72 @@ scm_clear_registered_modules ()
 
 /* Dispatch to the system dependent files
  *
- * They define these static functions:
+ * They define some static functions.  These functions are called with
+ * deferred interrupts.  When they want to throw errors, they are
+ * expected to insert a SCM_ALLOW_INTS before doing the throw.  It
+ * might work to throw an error while interrupts are deferred (because
+ * they will be unconditionally allowed the next time a SCM_ALLOW_INTS
+ * is executed, SCM_DEFER_INTS and SCM_ALLOW_INTS do not nest).
  */
 
 static void sysdep_dynl_init SCM_P ((void));
-static void *sysdep_dynl_link SCM_P ((char *filename, char *subr));
-static void sysdep_dynl_unlink SCM_P ((void *handle, char *subr));
-static void *sysdep_dynl_func SCM_P ((char *symbol, void *handle, char *subr));
+static void *sysdep_dynl_link SCM_P ((const char *filename, const char *subr));
+static void sysdep_dynl_unlink SCM_P ((void *handle, const char *subr));
+static void *sysdep_dynl_func SCM_P ((const char *symbol, void *handle,
+                                     const char *subr));
 
-#ifdef HAVE_LIBDL
+#ifdef HAVE_DLOPEN
 #include "dynl-dl.c"
 #else
 #ifdef HAVE_SHL_LOAD
 #include "dynl-shl.c"
 #else
-#ifdef HAVE_DLD
+#ifdef HAVE_LIBDLD
 #include "dynl-dld.c"
-#else /* no dynamic linking available */
-/* configure should not have defined DYNAMIC_LINKING in this case */
-#error Dynamic linking not implemented for your system.
+#else 
+
+/* no dynamic linking available, throw errors. */
+
+static void
+sysdep_dynl_init ()
+{
+}
+
+static void
+no_dynl_error (subr)
+     char *subr;
+{
+  SCM_ALLOW_INTS;
+  scm_misc_error (subr, "dynamic linking not available", SCM_EOL);
+}
+    
+static void *
+sysdep_dynl_link (filename, subr)
+     const char *filename;
+     const char *subr;
+{
+    no_dynl_error (subr);
+    return NULL;
+}
+
+static void 
+sysdep_dynl_unlink (handle, subr)
+     void *handle;
+     char *subr;
+{
+    no_dynl_error (subr);
+}
+
+static void *
+sysdep_dynl_func (symbol, handle, subr)
+     char *symbol;
+     void *handle;
+     char *subr;
+{
+    no_dynl_error (subr);
+    return NULL;
+}
+
 #endif
 #endif
 #endif
@@ -251,10 +303,18 @@ mark_dynl_obj (ptr)
      SCM ptr;
 {
     struct dynl_obj *d = (struct dynl_obj *)SCM_CDR (ptr);
-    SCM_SETGC8MARK (ptr);
     return d->filename;
 }
 
+static scm_sizet free_dynl_obj SCM_P ((SCM ptr));
+static scm_sizet
+free_dynl_obj (ptr)
+     SCM ptr;
+{
+  scm_must_free ((char *)SCM_CDR (ptr));
+  return sizeof (struct dynl_obj);
+}
+
 static int print_dynl_obj SCM_P ((SCM exp, SCM port, scm_print_state *pstate));
 static int
 print_dynl_obj (exp, port, pstate)
@@ -263,15 +323,17 @@ print_dynl_obj (exp, port, pstate)
      scm_print_state *pstate;
 {
     struct dynl_obj *d = (struct dynl_obj *)SCM_CDR (exp);
-    scm_gen_puts (scm_regular_string, "#<dynamic-object ", port);
+    scm_puts ("#<dynamic-object ", port);
     scm_iprin1 (d->filename, port, pstate);
-    scm_gen_putc ('>', port);
+    if (d->handle == NULL)
+      scm_puts (" (unlinked)", port);
+    scm_putc ('>', port);
     return 1;
 }
 
 static scm_smobfuns dynl_obj_smob = {
     mark_dynl_obj,
-    scm_free0,
+    free_dynl_obj,
     print_dynl_obj
 };
   
@@ -282,15 +344,19 @@ scm_dynamic_link (fname)
      SCM fname;
 {
     SCM z;
+    void *handle;
     struct dynl_obj *d;
 
     fname = scm_coerce_rostring (fname, s_dynamic_link, SCM_ARG1);
+
+    SCM_DEFER_INTS;
+    handle = sysdep_dynl_link (SCM_CHARS (fname), s_dynamic_link);
+
     d = (struct dynl_obj *)scm_must_malloc (sizeof (struct dynl_obj),
                                            s_dynamic_link);
     d->filename = fname;
+    d->handle = handle;
 
-    SCM_DEFER_INTS;
-    d->handle = sysdep_dynl_link (SCM_CHARS (fname), s_dynamic_link);
     SCM_NEWCELL (z);
     SCM_SETCHARS (z, d);
     SCM_SETCAR (z, scm_tc16_dynamic_obj);
@@ -299,11 +365,11 @@ scm_dynamic_link (fname)
     return z;
 }
 
-static struct dynl_obj *get_dynl_obj SCM_P ((SCM obj, char *subr, int argn));
+static struct dynl_obj *get_dynl_obj SCM_P ((SCM obj, const char *subr, int argn));
 static struct dynl_obj *
 get_dynl_obj (dobj, subr, argn)
      SCM dobj;
-     char *subr;
+     const char *subr;
      int argn;
 {
     struct dynl_obj *d;
@@ -330,9 +396,11 @@ scm_dynamic_unlink (dobj)
      SCM dobj;
 {
     struct dynl_obj *d = get_dynl_obj (dobj, s_dynamic_unlink, SCM_ARG1);
+    SCM_DEFER_INTS;
     sysdep_dynl_unlink (d->handle, s_dynamic_unlink);
     d->handle = NULL;
-    return SCM_BOOL_T;
+    SCM_ALLOW_INTS;
+    return SCM_UNSPECIFIED;
 }
 
 SCM_PROC (s_dynamic_func, "dynamic-func", 2, 0, 0, scm_dynamic_func);
@@ -346,7 +414,11 @@ scm_dynamic_func (SCM symb, SCM dobj)
     symb = scm_coerce_rostring (symb, s_dynamic_func, SCM_ARG1);
     d = get_dynl_obj (dobj, s_dynamic_func, SCM_ARG2);
 
-    func = sysdep_dynl_func (d->handle, SCM_CHARS (symb), s_dynamic_func);
+    SCM_DEFER_INTS;
+    func = (void (*) ()) sysdep_dynl_func (SCM_CHARS (symb), d->handle,
+                                          s_dynamic_func);
+    SCM_ALLOW_INTS;
+
     return scm_ulong2num ((unsigned long)func);
 }
 
@@ -360,8 +432,10 @@ scm_dynamic_call (SCM func, SCM dobj)
     if (SCM_NIMP (func) && SCM_ROSTRINGP (func))
        func = scm_dynamic_func (func, dobj);
     fptr = (void (*)()) scm_num2ulong (func, (char *)SCM_ARG1, s_dynamic_call);
+    SCM_DEFER_INTS;
     fptr ();
-    return SCM_BOOL_T;
+    SCM_ALLOW_INTS;
+    return SCM_UNSPECIFIED;
 }
 
 SCM_PROC (s_dynamic_args_call, "dynamic-args-call", 3, 0, 0, scm_dynamic_args_call);
@@ -379,12 +453,13 @@ scm_dynamic_args_call (func, dobj, args)
 
     fptr = (int (*)(int, char **)) scm_num2ulong (func, (char *)SCM_ARG1,
                                                   s_dynamic_args_call);
+    SCM_DEFER_INTS;
     argv = scm_make_argv_from_stringlist (args, &argc, s_dynamic_args_call,
                                          SCM_ARG3);
-
     result = (*fptr) (argc, argv);
-
     scm_must_free_argv (argv);
+    SCM_ALLOW_INTS;
+
     return SCM_MAKINUM(0L+result);
 }
 
@@ -395,13 +470,3 @@ scm_init_dynamic_linking ()
     sysdep_dynl_init ();
 #include "dynl.x"
 }
-
-#else /* not DYNAMIC_LINKING */
-
-void
-scm_init_dynamic_linking ()
-{
-#include "dynl.x"
-}
-
-#endif /* not DYNAMIC_LINKING */