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 --- */ 70static 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 85static 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 101static 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 117static 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 130static 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