Bug 549771 – improved .gitignore for glib
[platform/upstream/glib.git] / gmodule / gmodule-dl.c
index 6afc6d5..035b2a9 100644 (file)
@@ -1,25 +1,33 @@
 /* GMODULE - GLIB wrapper code for dynamic module loading
- * Copyright (C) 1998 Tim Janik
+ * Copyright (C) 1998, 2000 Tim Janik
  *
  * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
+ * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2 of the License, or (at your option) any later version.
  *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the GNU
- * Library General Public License for more details.
+ * Lesser General Public License for more details.
  *
- * You should have received a copy of the GNU Library General Public
+ * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
 
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
 /* 
  * MT safe
  */
+#include "config.h"
 
 #include <dlfcn.h>
 
  * RTLD_GLOBAL - the external symbols defined in the library will be made
  *              available to subsequently loaded libraries.
  */
-#ifndef        RTLD_GLOBAL
-#define        RTLD_GLOBAL     0
-#endif /* RTLD_GLOBAL */
 #ifndef        RTLD_LAZY
 #define        RTLD_LAZY       1
 #endif /* RTLD_LAZY */
 #ifndef        RTLD_NOW
 #define        RTLD_NOW        0
 #endif /* RTLD_NOW */
+/* some systems (OSF1 V5.0) have broken RTLD_GLOBAL linkage */
+#ifdef G_MODULE_BROKEN_RTLD_GLOBAL
+#undef RTLD_GLOBAL
+#endif /* G_MODULE_BROKEN_RTLD_GLOBAL */
+#ifndef        RTLD_GLOBAL
+#define        RTLD_GLOBAL     0
+#endif /* RTLD_GLOBAL */
 
 
 /* --- functions --- */
+static gchar*
+fetch_dlerror (gboolean replace_null)
+{
+  gchar *msg = dlerror ();
+
+  /* make sure we always return an error message != NULL, if
+   * expected to do so. */
+
+  if (!msg && replace_null)
+    return "unknown dl-error";
+
+  return msg;
+}
+
 static gpointer
-_g_module_open (const gchar    *file_name,
-               gboolean        bind_lazy)
+_g_module_open (const gchar *file_name,
+               gboolean     bind_lazy,
+               gboolean     bind_local)
 {
   gpointer handle;
   
-  handle = dlopen (file_name, RTLD_GLOBAL | (bind_lazy ? RTLD_LAZY : RTLD_NOW));
+  handle = dlopen (file_name,
+                  (bind_local ? 0 : RTLD_GLOBAL) | (bind_lazy ? RTLD_LAZY : RTLD_NOW));
   if (!handle)
-    g_module_set_error (dlerror ());
+    g_module_set_error (fetch_dlerror (TRUE));
   
   return handle;
 }
@@ -87,14 +115,14 @@ _g_module_self (void)
   
   handle = dlopen (NULL, RTLD_GLOBAL | RTLD_LAZY);
   if (!handle)
-    g_module_set_error (dlerror ());
+    g_module_set_error (fetch_dlerror (TRUE));
   
   return handle;
 }
 
 static void
-_g_module_close (gpointer        handle,
-                gboolean         is_unref)
+_g_module_close (gpointer handle,
+                gboolean is_unref)
 {
   /* are there any systems out there that have dlopen()/dlclose()
    * without a reference count implementation?
@@ -104,19 +132,22 @@ _g_module_close (gpointer   handle,
   if (is_unref)
     {
       if (dlclose (handle) != 0)
-       g_module_set_error (dlerror ());
+       g_module_set_error (fetch_dlerror (TRUE));
     }
 }
 
 static gpointer
-_g_module_symbol (gpointer       handle,
-                 const gchar    *symbol_name)
+_g_module_symbol (gpointer     handle,
+                 const gchar *symbol_name)
 {
   gpointer p;
-  
+  gchar *msg;
+
+  fetch_dlerror (FALSE);
   p = dlsym (handle, symbol_name);
-  if (!p)
-    g_module_set_error (dlerror ());
+  msg = fetch_dlerror (FALSE);
+  if (msg)
+    g_module_set_error (msg);
   
   return p;
 }
@@ -129,9 +160,9 @@ _g_module_build_path (const gchar *directory,
     if (strncmp (module_name, "lib", 3) == 0)
       return g_strconcat (directory, "/", module_name, NULL);
     else
-      return g_strconcat (directory, "/lib", module_name, ".so", NULL);
+      return g_strconcat (directory, "/lib", module_name, "." G_MODULE_SUFFIX, NULL);
   } else if (strncmp (module_name, "lib", 3) == 0)
     return g_strdup (module_name);
   else
-    return g_strconcat ("lib", module_name, ".so", NULL);
+    return g_strconcat ("lib", module_name, "." G_MODULE_SUFFIX, NULL);
 }