Main Page | Class List | Directories | File List | Class Members | File Members

gmodule-dl.c

Go to the documentation of this file.
00001 /* GMODULE - GLIB wrapper code for dynamic module loading
00002  * Copyright (C) 1998, 2000 Tim Janik
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Library General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Library General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Library General Public
00015  * License along with this library; if not, write to the
00016  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00017  * Boston, MA 02111-1307, USA.
00018  */
00019 
00020 /*
00021  * Modified by the GLib Team and others 1997-1999.  See the AUTHORS
00022  * file for a list of people on the GLib Team.  See the ChangeLog
00023  * files for a list of changes.  These files are distributed with
00024  * GLib at ftp://ftp.gtk.org/pub/gtk/. 
00025  */
00026 
00027 /* 
00028  * MT safe
00029  */
00030 
00031 #include <dlfcn.h>
00032 
00033 /* Perl includes <nlist.h> and <link.h> instead of <dlfcn.h> on some systmes? */
00034 
00035 
00036 /* dlerror() is not implemented on all systems
00037  */
00038 #ifndef G_MODULE_HAVE_DLERROR
00039 #  ifdef __NetBSD__
00040 #    define dlerror()   g_strerror (errno)
00041 #  else /* !__NetBSD__ */
00042 /* could we rely on errno's state here? */
00043 #    define dlerror()   "unknown dl-error"
00044 #  endif /* !__NetBSD__ */
00045 #endif  /* G_MODULE_HAVE_DLERROR */
00046 
00047 /* some flags are missing on some systems, so we provide
00048  * harmless defaults.
00049  * The Perl sources say, RTLD_LAZY needs to be defined as (1),
00050  * at least for Solaris 1.
00051  *
00052  * Mandatory:
00053  * RTLD_LAZY   - resolve undefined symbols as code from the dynamic library
00054  *               is executed.
00055  * RTLD_NOW    - resolve all undefined symbols before dlopen returns, and fail
00056  *               if this cannot be done.
00057  * Optionally:
00058  * RTLD_GLOBAL - the external symbols defined in the library will be made
00059  *               available to subsequently loaded libraries.
00060  */
00061 #ifndef RTLD_LAZY
00062 #define RTLD_LAZY       1
00063 #endif  /* RTLD_LAZY */
00064 #ifndef RTLD_NOW
00065 #define RTLD_NOW        0
00066 #endif  /* RTLD_NOW */
00067 /* some systems (OSF1 V5.0) have broken RTLD_GLOBAL linkage */
00068 #ifdef G_MODULE_BROKEN_RTLD_GLOBAL
00069 #undef  RTLD_GLOBAL
00070 #endif /* G_MODULE_BROKEN_RTLD_GLOBAL */
00071 #ifndef RTLD_GLOBAL
00072 #define RTLD_GLOBAL     0
00073 #endif  /* RTLD_GLOBAL */
00074 
00075 
00076 /* --- functions --- */
00077 static gchar*
00078 fetch_dlerror (void)
00079 {
00080   gchar *msg = dlerror ();
00081 
00082   /* make sure we always return an error message != NULL */
00083 
00084   return msg ? msg : "unknown dl-error";
00085 }
00086 
00087 static gpointer
00088 _g_module_open (const gchar *file_name,
00089                 gboolean     bind_lazy)
00090 {
00091   gpointer handle;
00092   
00093   handle = dlopen (file_name, RTLD_GLOBAL | (bind_lazy ? RTLD_LAZY : RTLD_NOW));
00094   if (!handle)
00095     g_module_set_error (fetch_dlerror ());
00096   
00097   return handle;
00098 }
00099 
00100 static gpointer
00101 _g_module_self (void)
00102 {
00103   gpointer handle;
00104   
00105   /* to query symbols from the program itself, special link options
00106    * are required on some systems.
00107    */
00108   
00109   handle = dlopen (NULL, RTLD_GLOBAL | RTLD_LAZY);
00110   if (!handle)
00111     g_module_set_error (fetch_dlerror ());
00112   
00113   return handle;
00114 }
00115 
00116 static void
00117 _g_module_close (gpointer handle,
00118                  gboolean is_unref)
00119 {
00120   /* are there any systems out there that have dlopen()/dlclose()
00121    * without a reference count implementation?
00122    */
00123   is_unref |= 1;
00124   
00125   if (is_unref)
00126     {
00127       if (dlclose (handle) != 0)
00128         g_module_set_error (fetch_dlerror ());
00129     }
00130 }
00131 
00132 static gpointer
00133 _g_module_symbol (gpointer     handle,
00134                   const gchar *symbol_name)
00135 {
00136   gpointer p;
00137   
00138   p = dlsym (handle, symbol_name);
00139   if (!p)
00140     g_module_set_error (fetch_dlerror ());
00141   
00142   return p;
00143 }
00144 
00145 static gchar*
00146 _g_module_build_path (const gchar *directory,
00147                       const gchar *module_name)
00148 {
00149   if (directory && *directory) {
00150     if (strncmp (module_name, "lib", 3) == 0)
00151       return g_strconcat (directory, "/", module_name, NULL);
00152     else
00153       return g_strconcat (directory, "/lib", module_name, ".so", NULL);
00154   } else if (strncmp (module_name, "lib", 3) == 0)
00155     return g_strdup (module_name);
00156   else
00157     return g_strconcat ("lib", module_name, ".so", NULL);
00158 }

© sourcejam.com 2005-2008