gmodule-dl.c revision a6149403deed931b8c78b26aeb0e9c952cf3ef93
1/* GMODULE - GLIB wrapper code for dynamic module loading 2 * Copyright (C) 1998 Tim Janik 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Library 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 * Library General Public License for more details. 13 * 14 * You should have received a copy of the GNU Library 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#include <dlfcn.h> 20 21/* Perl includes <nlist.h> and <link.h> instead of <dlfcn.h> on some systmes? */ 22 23 24/* dlerror() is not implemented on all systems 25 */ 26#ifndef G_MODULE_HAVE_DLERROR 27# ifdef __NetBSD__ 28# define dlerror() g_strerror (errno) 29# else /* !__NetBSD__ */ 30/* could we rely on errno's state here? */ 31# define dlerror() "unknown dl-error" 32# endif /* !__NetBSD__ */ 33#endif /* G_MODULE_HAVE_DLERROR */ 34 35/* some flags are missing on some systems, so we provide 36 * harmless defaults. 37 * The Perl sources say, RTLD_LAZY needs to be defined as (1), 38 * at least for Solaris 1. 39 * 40 * Mandatory: 41 * RTLD_LAZY - resolve undefined symbols as code from the dynamic library 42 * is executed. 43 * RTLD_NOW - resolve all undefined symbols before dlopen returns, and fail 44 * if this cannot be done. 45 * Optionally: 46 * RTLD_GLOBAL - the external symbols defined in the library will be made 47 * available to subsequently loaded libraries. 48 */ 49#ifndef RTLD_GLOBAL 50#define RTLD_GLOBAL 0 51#endif /* RTLD_GLOBAL */ 52#ifndef RTLD_LAZY 53#define RTLD_LAZY 1 54#endif /* RTLD_LAZY */ 55#ifndef RTLD_NOW 56#define RTLD_NOW 0 57#endif /* RTLD_NOW */ 58 59 60/* --- functions --- */ 61static gpointer 62_g_module_open (const gchar *file_name, 63 gboolean bind_lazy) 64{ 65 gpointer handle; 66 67 handle = dlopen (file_name, RTLD_GLOBAL | (bind_lazy ? RTLD_LAZY : RTLD_NOW)); 68 if (!handle) 69 g_module_set_error (dlerror ()); 70 71 return handle; 72} 73 74static gpointer 75_g_module_self (void) 76{ 77 gpointer handle; 78 79 /* to query symbols from the program itself, special link options 80 * are required on some systems. 81 */ 82 83 handle = dlopen (NULL, RTLD_GLOBAL | RTLD_LAZY); 84 if (!handle) 85 g_module_set_error (dlerror ()); 86 87 return handle; 88} 89 90static void 91_g_module_close (gpointer handle, 92 gboolean is_unref) 93{ 94 /* are there any systems out there that have dlopen()/dlclose() 95 * without a reference count implementation? 96 */ 97 is_unref |= 1; 98 99 if (is_unref) 100 { 101 if (dlclose (handle) != 0) 102 g_module_set_error (dlerror ()); 103 } 104} 105 106static gpointer 107_g_module_symbol (gpointer handle, 108 const gchar *symbol_name) 109{ 110 gpointer p; 111 112 p = dlsym (handle, symbol_name); 113 if (!p) 114 g_module_set_error (dlerror ()); 115 116 return p; 117} 118 119static gchar* 120_g_module_build_path (const gchar *directory, 121 const gchar *module_name) 122{ 123 if (directory) 124 return g_strconcat (directory, "/lib", module_name, ".so", NULL); 125 else 126 return g_strconcat ("lib", module_name, ".so", NULL); 127} 128