From fac803a223b47d7abbfbf3a2adee2f1862382582 Mon Sep 17 00:00:00 2001 From: Tim Janik Date: Mon, 10 Aug 1998 01:36:18 +0000 Subject: [PATCH] minor changes to internal interface. Mon Aug 10 03:35:57 1998 Tim Janik * gmodule.c: minor changes to internal interface. * gmodule-dl.c: * gmodule-dld.c: put some comments into the files, and provided better error checking for shl_findsym(). whish i had a system to test this stuff on. --- gmodule/ChangeLog | 8 +++++ gmodule/gmodule-dl.c | 41 +++++++++++++++---------- gmodule/gmodule-dld.c | 82 ++++++++++++++++++++++++++++++++++---------------- gmodule/gmodule.c | 83 ++++++++++++++++++++++++++------------------------- gmodule/gmodule.h | 4 +-- 5 files changed, 134 insertions(+), 84 deletions(-) diff --git a/gmodule/ChangeLog b/gmodule/ChangeLog index 2fcde62..d96c408 100644 --- a/gmodule/ChangeLog +++ b/gmodule/ChangeLog @@ -1,3 +1,11 @@ +Mon Aug 10 03:35:57 1998 Tim Janik + + * gmodule.c: minor changes to internal interface. + * gmodule-dl.c: + * gmodule-dld.c: put some comments into the files, and provided + better error checking for shl_findsym(). whish i had a system to + test this stuff on. + Mon Aug 10 02:18:31 1998 Tim Janik * Makefile.am (lib_LTLIBRARIES): for now, skip the dependency on diff --git a/gmodule/gmodule-dl.c b/gmodule/gmodule-dl.c index 09d4bd5..4eb1b4a 100644 --- a/gmodule/gmodule-dl.c +++ b/gmodule/gmodule-dl.c @@ -8,7 +8,7 @@ * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public @@ -36,6 +36,15 @@ * harmless defaults. * The Perl sources say, RTLD_LAZY needs to be defined as (1), * at least for Solaris 1. + * + * Mandatory: + * RTLD_LAZY - resolve undefined symbols as code from the dynamic library + * is executed. + * RTLD_NOW - resolve all undefined symbols before dlopen returns, and fail + * if this cannot be done. + * Optionally: + * RTLD_GLOBAL - the external symbols defined in the library will be made + * available to subsequently loaded libraries. */ #ifndef RTLD_GLOBAL #define RTLD_GLOBAL 0 @@ -51,14 +60,14 @@ /* --- functions --- */ static gpointer _g_module_open (const gchar *file_name, - gboolean bind_lazy) + gboolean bind_lazy) { gpointer handle; - + handle = dlopen (file_name, RTLD_GLOBAL | (bind_lazy ? RTLD_LAZY : RTLD_NOW)); if (!handle) g_module_set_error (dlerror ()); - + return handle; } @@ -66,43 +75,43 @@ static gpointer _g_module_self (void) { gpointer handle; - + /* to query symbols from the program itself, special link options * are required on some systems. */ - + handle = dlopen (NULL, RTLD_GLOBAL | RTLD_LAZY); if (!handle) g_module_set_error (dlerror ()); - + return handle; } static void -_g_module_close (gpointer *handle_p, - gboolean is_unref) +_g_module_close (gpointer handle, + gboolean is_unref) { /* are there any systems out there that have dlopen()/dlclose() * without a reference count implementation? */ is_unref |= 1; - + if (is_unref) { - if (dlclose (*handle_p) != 0) + if (dlclose (handle) != 0) g_module_set_error (dlerror ()); } } static gpointer -_g_module_symbol (gpointer *handle_p, - const gchar *symbol_name) +_g_module_symbol (gpointer handle, + const gchar *symbol_name) { gpointer p; - - p = dlsym (*handle_p, symbol_name); + + p = dlsym (handle, symbol_name); if (!p) g_module_set_error (dlerror ()); - + return p; } diff --git a/gmodule/gmodule-dld.c b/gmodule/gmodule-dld.c index 1e5c3fa..552b8fa 100644 --- a/gmodule/gmodule-dld.c +++ b/gmodule/gmodule-dld.c @@ -8,7 +8,7 @@ * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public @@ -21,62 +21,94 @@ /* some flags are missing on some systems, so we provide * harmless defaults. + * + * Mandatory: + * BIND_IMMEDIATE - Resolve symbol references when the library is loaded. + * BIND_DEFERRED - Delay code symbol resolution until actual reference. + * + * Optionally: + * BIND_FIRST - Place the library at the head of the symbol search order. + * BIND_NONFATAL - The default BIND_IMMEDIATE behavior is to treat all unsatisfied + * symbols as fatal. This flag allows binding of unsatisfied code + * symbols to be deferred until use. + * [Perl: For certain libraries, like DCE, deferred binding often + * causes run time problems. Adding BIND_NONFATAL to BIND_IMMEDIATE + * still allows unresolved references in situations like this.] + * BIND_NOSTART - Do not call the initializer for the shared library when the + * library is loaded, nor on a future call to shl_unload(). + * BIND_VERBOSE - Print verbose messages concerning possible unsatisfied symbols. + * + * hp9000s700/hp9000s800: + * BIND_RESTRICTED - Restrict symbols visible by the library to those present at + * library load time. + * DYNAMIC_PATH - Allow the loader to dynamically search for the library specified + * by the path argument. */ #ifndef DYNAMIC_PATH #define DYNAMIC_PATH 0 #endif /* DYNAMIC_PATH */ +#ifndef BIND_RESTRICTED +#define BIND_RESTRICTED 0 +#endif /* BIND_RESTRICTED */ -/* should we have BIND_TOGETHER here as well? */ -#define CONST_BIND_FLAGS (BIND_NONFATAL | BIND_VERBOSE) +#define OPT_BIND_FLAGS (BIND_NONFATAL | BIND_VERBOSE) /* --- functions --- */ static gpointer _g_module_open (const gchar *file_name, - gboolean bind_lazy) + gboolean bind_lazy) { - gpointer handle; - - handle = shl_load (file_name, CONST_BIND_FLAGS | (bind_lazy ? BIND_DEFERRED : BIND_IMMEDIATE), 0); - if (!handle) - g_module_set_error (g_strerror (errno)); - - return handle; + shl_t shl_handle; + + shl_handle = shl_load (file_name, + (bind_lazy ? BIND_DEFERRED : BIND_IMMEDIATE) | OPT_BIND_FLAGS, 0); + if (!shl_handle) + { + /* the hp-docs say we should better abort() if errno==ENOSYM ;( */ + g_module_set_error (g_strerror (errno)); + } + + return (gpointer) shl_handle; } static gpointer _g_module_self (void) { - gpointer handle; - - handle = PROG_HANDLE; - if (!handle) + shl_t shl_handle; + + shl_handle = PROG_HANDLE; + if (!shl_handle) g_module_set_error (g_strerror (errno)); - - return handle; + + return shl_handle; } static void -_g_module_close (gpointer *handle_p, - gboolean is_unref) +_g_module_close (gpointer handle, + gboolean is_unref) { if (!is_unref) { - if (shl_unload (*handle_p) != 0) + if (shl_unload ((shl_t) handle) != 0) g_module_set_error (g_strerror (errno)); } } static gpointer -_g_module_symbol (gpointer *handle_p, - const gchar *symbol_name) +_g_module_symbol (gpointer handle, + const gchar *symbol_name) { gpointer p = NULL; - + /* should we restrict lookups to TYPE_PROCEDURE? */ - if (shl_findsym (handle_p, symbol_name, TYPE_UNDEFINED, &p) != 0 || p == NULL) - g_module_set_error (g_strerror (errno)); + if (shl_findsym ((shl_t*) &handle, symbol_name, TYPE_UNDEFINED, &p) != 0 || + handle == NULL || p == NULL) + { + /* the hp-docs say we should better abort() if errno==ENOSYM ;( */ + g_module_set_error (g_strerror (errno)); + } return p; } diff --git a/gmodule/gmodule.c b/gmodule/gmodule.c index 6d90830..9aaa608 100644 --- a/gmodule/gmodule.c +++ b/gmodule/gmodule.c @@ -8,7 +8,7 @@ * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public @@ -24,9 +24,10 @@ /* We maintain a list of modules, so we can reference count them. * That's needed because some platforms don't support refernce counts on - * modules (http://www.stat.umn.edu/~luke/xls/projects/dlbasics/dlbasics.html). + * modules e.g. the shl_* implementation of HP-UX + * (http://www.stat.umn.edu/~luke/xls/projects/dlbasics/dlbasics.html). * Also, the module for the program itself is kept seperatedly for - * faster access. + * faster access and because it has special semantics. */ @@ -44,10 +45,10 @@ struct _GModule /* --- prototypes --- */ static gpointer _g_module_open (const gchar *file_name, gboolean bind_lazy); -static void _g_module_close (gpointer *handle_p, +static void _g_module_close (gpointer handle, gboolean is_unref); static gpointer _g_module_self (void); -static gpointer _g_module_symbol (gpointer *handle_p, +static gpointer _g_module_symbol (gpointer handle, const gchar *symbol_name); static inline void g_module_set_error (const gchar *error); static inline GModule* g_module_find_by_handle (gpointer handle); @@ -65,10 +66,10 @@ static inline GModule* g_module_find_by_handle (gpointer handle) { GModule *module; - + if (main_module && main_module->handle == handle) return main_module; - + for (module = modules; module; module = module->next) if (handle == module->handle) return module; @@ -79,7 +80,7 @@ static inline GModule* g_module_find_by_name (const gchar *name) { GModule *module; - + for (module = modules; module; module = module->next) if (strcmp (name, module->file_name) == 0) return module; @@ -116,7 +117,7 @@ gboolean g_module_supported (void) { CHECK_ERROR (FALSE); - + return TRUE; } @@ -126,9 +127,9 @@ g_module_open (const gchar *file_name, { GModule *module; gpointer handle; - + CHECK_ERROR (NULL); - + if (!file_name) { if (!main_module) @@ -144,19 +145,19 @@ g_module_open (const gchar *file_name, main_module->next = NULL; } } - + return main_module; } - + /* we first search the module list by name */ module = g_module_find_by_name (file_name); if (module) { module->ref_count++; - + return module; } - + /* open the module */ handle = _g_module_open (file_name, (flags & G_MODULE_BIND_LAZY) != 0); if (handle) @@ -164,22 +165,22 @@ g_module_open (const gchar *file_name, gchar *saved_error; GModuleCheckInit check_init; gboolean check_failed = FALSE; - + /* search the module list by handle, since file names are not unique */ module = g_module_find_by_handle (handle); if (module) { - _g_module_close (&module->handle, TRUE); + _g_module_close (module->handle, TRUE); module->ref_count++; g_module_set_error (NULL); - + return module; } - + saved_error = module_error; module_error = NULL; g_module_set_error (NULL); - + module = g_new (GModule, 1); module->file_name = g_strdup (file_name); module->handle = handle; @@ -187,15 +188,15 @@ g_module_open (const gchar *file_name, module->de_init = NULL; module->next = modules; modules = module; - + /* check initialization */ if (g_module_symbol (module, "g_module_check_init", (gpointer) &check_init)) check_failed = check_init (module); - + /* we don't call de_init() if the initialization check failed. */ if (!check_failed) g_module_symbol (module, "g_module_de_init", (gpointer) &module->de_init); - + if (check_failed) { g_module_close (module); @@ -206,12 +207,12 @@ g_module_open (const gchar *file_name, g_module_set_error (saved_error); g_free (saved_error); } - + return module; } gboolean -g_module_close (GModule *module) +g_module_close (GModule *module) { CHECK_ERROR (FALSE); @@ -227,7 +228,7 @@ g_module_close (GModule *module) { GModule *last; GModule *node; - + last = NULL; node = modules; while (node) @@ -244,13 +245,13 @@ g_module_close (GModule *module) node = last->next; } module->next = NULL; - - _g_module_close (&module->handle, FALSE); + + _g_module_close (module->handle, FALSE); g_free (module->file_name); - + g_free (module); } - + return module_error == NULL; } @@ -261,32 +262,32 @@ g_module_error (void) } gboolean -g_module_symbol (GModule *module, - const gchar *symbol_name, - gconstpointer *symbol) +g_module_symbol (GModule *module, + const gchar *symbol_name, + gconstpointer *symbol) { if (symbol) *symbol = NULL; CHECK_ERROR (FALSE); - + g_return_val_if_fail (module != NULL, FALSE); g_return_val_if_fail (symbol_name != NULL, FALSE); g_return_val_if_fail (symbol != NULL, FALSE); - + #ifdef G_MODULE_NEED_USCORE symbol_name = g_strconcat ("_", symbol_name, NULL); - *symbol = _g_module_symbol (&module->handle, symbol_name); + *symbol = _g_module_symbol (module->handle, symbol_name); g_free (symbol_name); #else /* !G_MODULE_NEED_USCORE */ - *symbol = _g_module_symbol (&module->handle, symbol_name); + *symbol = _g_module_symbol (module->handle, symbol_name); #endif /* !G_MODULE_NEED_USCORE */ - + if (module_error) { *symbol = NULL; return FALSE; } - + return TRUE; } @@ -294,9 +295,9 @@ gchar* g_module_name (GModule *module) { g_return_val_if_fail (module != NULL, NULL); - + if (module == main_module) return "main"; - + return module->file_name; } diff --git a/gmodule/gmodule.h b/gmodule/gmodule.h index fd63af3..58c268f 100644 --- a/gmodule/gmodule.h +++ b/gmodule/gmodule.h @@ -8,7 +8,7 @@ * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public @@ -61,7 +61,7 @@ gchar* g_module_error (void); /* retrive a symbol pointer from `module', returns TRUE on success */ gboolean g_module_symbol (GModule *module, const gchar *symbol_name, - gconstpointer *symbol); + gconstpointer *symbol); /* retrive the file name from an existing module */ gchar* g_module_name (GModule *module); -- 2.7.4