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 <dl.h> 00032 00033 00034 /* some flags are missing on some systems, so we provide 00035 * harmless defaults. 00036 * 00037 * Mandatory: 00038 * BIND_IMMEDIATE - Resolve symbol references when the library is loaded. 00039 * BIND_DEFERRED - Delay code symbol resolution until actual reference. 00040 * 00041 * Optionally: 00042 * BIND_FIRST - Place the library at the head of the symbol search order. 00043 * BIND_NONFATAL - The default BIND_IMMEDIATE behavior is to treat all unsatisfied 00044 * symbols as fatal. This flag allows binding of unsatisfied code 00045 * symbols to be deferred until use. 00046 * [Perl: For certain libraries, like DCE, deferred binding often 00047 * causes run time problems. Adding BIND_NONFATAL to BIND_IMMEDIATE 00048 * still allows unresolved references in situations like this.] 00049 * BIND_NOSTART - Do not call the initializer for the shared library when the 00050 * library is loaded, nor on a future call to shl_unload(). 00051 * BIND_VERBOSE - Print verbose messages concerning possible unsatisfied symbols. 00052 * 00053 * hp9000s700/hp9000s800: 00054 * BIND_RESTRICTED - Restrict symbols visible by the library to those present at 00055 * library load time. 00056 * DYNAMIC_PATH - Allow the loader to dynamically search for the library specified 00057 * by the path argument. 00058 */ 00059 #ifndef DYNAMIC_PATH 00060 #define DYNAMIC_PATH 0 00061 #endif /* DYNAMIC_PATH */ 00062 #ifndef BIND_RESTRICTED 00063 #define BIND_RESTRICTED 0 00064 #endif /* BIND_RESTRICTED */ 00065 00066 #define OPT_BIND_FLAGS (BIND_NONFATAL | BIND_VERBOSE) 00067 00068 00069 /* --- functions --- */ 00070 static gpointer 00071 _g_module_open (const gchar *file_name, 00072 gboolean bind_lazy) 00073 { 00074 shl_t shl_handle; 00075 00076 shl_handle = shl_load (file_name, 00077 (bind_lazy ? BIND_DEFERRED : BIND_IMMEDIATE) | OPT_BIND_FLAGS, 0); 00078 if (!shl_handle) 00079 { 00080 /* the hp-docs say we should better abort() if errno==ENOSYM ;( */ 00081 g_module_set_error (g_strerror (errno)); 00082 } 00083 00084 return (gpointer) shl_handle; 00085 } 00086 00087 static gpointer 00088 _g_module_self (void) 00089 { 00090 shl_t shl_handle; 00091 00092 shl_handle = PROG_HANDLE; 00093 if (!shl_handle) 00094 g_module_set_error (g_strerror (errno)); 00095 00096 return shl_handle; 00097 } 00098 00099 static void 00100 _g_module_close (gpointer handle, 00101 gboolean is_unref) 00102 { 00103 if (!is_unref) 00104 { 00105 if (shl_unload ((shl_t) handle) != 0) 00106 g_module_set_error (g_strerror (errno)); 00107 } 00108 } 00109 00110 static gpointer 00111 _g_module_symbol (gpointer handle, 00112 const gchar *symbol_name) 00113 { 00114 gpointer p = NULL; 00115 00116 /* should we restrict lookups to TYPE_PROCEDURE? 00117 */ 00118 if (handle == PROG_HANDLE) 00119 { 00120 /* PROG_HANDLE will only lookup symbols in the program itself, not honouring 00121 * libraries. passing NULL as a handle will also try to lookup the symbol 00122 * in currently loaded libraries. fix pointed out and supplied by: 00123 * David Gero <dgero@nortelnetworks.com> 00124 */ 00125 handle = NULL; 00126 } 00127 if (shl_findsym ((shl_t*) &handle, symbol_name, TYPE_UNDEFINED, &p) != 0 || 00128 handle == NULL || p == NULL) 00129 { 00130 /* the hp-docs say we should better abort() if errno==ENOSYM ;( */ 00131 g_module_set_error (g_strerror (errno)); 00132 } 00133 00134 return p; 00135 } 00136 00137 static gchar* 00138 _g_module_build_path (const gchar *directory, 00139 const gchar *module_name) 00140 { 00141 if (directory && *directory) 00142 if (strncmp (module_name, "lib", 3) == 0) 00143 return g_strconcat (directory, "/", module_name, NULL); 00144 else 00145 return g_strconcat (directory, "/lib", module_name, ".sl", NULL); 00146 else if (strncmp (module_name, "lib", 3) == 0) 00147 return g_strdup (module_name); 00148 else 00149 return g_strconcat ("lib", module_name, ".sl", NULL); 00150 }