1 /* GMODULE - GLIB wrapper code for dynamic module loading 2 * Copyright (C) 1998, 2000 Tim Janik 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the 16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 * Boston, MA 02111-1307, USA. 18 */ 19 20 /* 21 * Modified by the GLib Team and others 1997-2000. See the AUTHORS 22 * file for a list of people on the GLib Team. See the ChangeLog 23 * files for a list of changes. These files are distributed with 24 * GLib at ftp://ftp.gtk.org/pub/gtk/. 25 */ 26 27 /* 28 * MT safe 29 */ 30 #include "config.h" 31 32 #include <dlfcn.h> 33 34 /* Perl includes <nlist.h> and <link.h> instead of <dlfcn.h> on some systmes? */ 35 36 37 /* dlerror() is not implemented on all systems 38 */ 39 #ifndef G_MODULE_HAVE_DLERROR 40 /* could we rely on errno's state here? */ 41 # define dlerror() "unknown dl-error" 42 #endif /* G_MODULE_HAVE_DLERROR */ 43 44 /* some flags are missing on some systems, so we provide 45 * harmless defaults. 46 * The Perl sources say, RTLD_LAZY needs to be defined as (1), 47 * at least for Solaris 1. 48 * 49 * Mandatory: 50 * RTLD_LAZY - resolve undefined symbols as code from the dynamic library 51 * is executed. 52 * RTLD_NOW - resolve all undefined symbols before dlopen returns, and fail 53 * if this cannot be done. 54 * Optionally: 55 * RTLD_GLOBAL - the external symbols defined in the library will be made 56 * available to subsequently loaded libraries. 57 */ 58 #ifndef RTLD_GLOBAL 59 #define RTLD_GLOBAL 0 60 #endif /* RTLD_GLOBAL */ 61 #ifndef RTLD_LAZY 62 #define RTLD_LAZY 1 63 #endif /* RTLD_LAZY */ 64 #ifndef RTLD_NOW 65 #define RTLD_NOW 0 66 #endif /* RTLD_NOW */ 67 68 69 /* --- functions --- */ 70 static gpointer 71 _g_module_open (const gchar *file_name, 72 gboolean bind_lazy, 73 gboolean bind_local) 74 { 75 gpointer handle; 76 77 handle = dlopen (file_name, 78 (bind_local ? 0 : RTLD_GLOBAL) | (bind_lazy ? RTLD_LAZY : RTLD_NOW)); 79 if (!handle) 80 g_module_set_error (dlerror ()); 81 82 return handle; 83 } 84 85 static gpointer 86 _g_module_self (void) 87 { 88 gpointer handle; 89 90 /* to query symbols from the program itself, special link options 91 * are required on some systems. 92 */ 93 94 /* XXX, not supported */ 95 handle = NULL; 96 g_module_set_error ("module handle for self not supported"); 97 98 return handle; 99 } 100 101 static void 102 _g_module_close (gpointer handle, 103 gboolean is_unref) 104 { 105 /* are there any systems out there that have dlopen()/dlclose() 106 * without a reference count implementation? 107 */ 108 is_unref |= 1; 109 110 if (is_unref) 111 { 112 /* XXX, no return code */ 113 dlclose (handle); 114 } 115 } 116 117 static gpointer 118 _g_module_symbol (gpointer handle, 119 const gchar *symbol_name) 120 { 121 gpointer p; 122 123 p = dlsym (handle, symbol_name); 124 if (!p) 125 g_module_set_error (dlerror ()); 126 127 return p; 128 } 129 130 static gchar* 131 _g_module_build_path (const gchar *directory, 132 const gchar *module_name) 133 { 134 gchar *suffix = strrchr(module_name, '.'); 135 if (directory && *directory) 136 if (suffix && (stricmp (suffix, ".dll") == 0)) 137 return g_strconcat (directory, "/", module_name, NULL); 138 else 139 return g_strconcat (directory, "/", module_name, ".dll", NULL); 140 else if (suffix && (stricmp (suffix, ".dll") == 0)) 141 return g_strdup (module_name); 142 else 143 return g_strconcat (module_name, ".dll", NULL); 144 } 145