mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-19 16:52:11 +01:00
Determine the suffix of the shared librarries for this system. This is
2000-12-22 Sebastian Wilhelmi <wilhelmi@ira.uka.de> * configure.in: Determine the suffix of the shared librarries for this system. This is done analogous to ltconfig.sh. G_MODULE_SUFFIX in glibconfig.h is set to either "sl", "dll", or (most often) "so". * tests/Makefile.am, tests/module-test.c, tests/libmoduletestplugin_a.c, tests/libmoduletestplugin_b.c: Added new testcase for gmodule. This is mostly copied from gmodule/testgmodule.c, but unlike that is is quiet. (Why BTW are some tests that verbose, not to say loquacious...) * gmodule.c: Make g_module_open more tolerant wrt to the module name. First it tries to open the module as named, if that fails, it checks, whether it is a libtool archive and parses it, if that fails it appends the systems shared library suffix (i.e. ".so") (if not already found) and tries again and if that fails it tries to append the ".la" libtool suffix (if not already found) and parses it. * gmodule.c: Lock recursive mutex during most module functions for safety. * gmodule-dl.c: Return an error from _g_module_symbol only, if dlerror says so. All other functions return an error as well, if dlerror returns NULL. * testgmodule.c: Thanks to the above change the #ifdefs have vanished. * glib/glib-sections.txt: Added G_MODULE_SUFFIX. * glib/tmpl/modules.sgml: Updated.
This commit is contained in:
parent
32241715f4
commit
57a7a2b010
13
ChangeLog
13
ChangeLog
@ -1,3 +1,16 @@
|
||||
2000-12-22 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* configure.in: Determine the suffix of the shared librarries for
|
||||
this system. This is done analogous to
|
||||
ltconfig.sh. G_MODULE_SUFFIX in glibconfig.h is set to either
|
||||
"sl", "dll", or (most often) "so".
|
||||
|
||||
* tests/Makefile.am, tests/module-test.c,
|
||||
tests/libmoduletestplugin_a.c, tests/libmoduletestplugin_b.c:
|
||||
Added new testcase for gmodule. This is mostly copied from
|
||||
gmodule/testgmodule.c, but unlike that is is quiet. (Why BTW are
|
||||
some tests that verbose, not to say loquacious...)
|
||||
|
||||
2000-12-19 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* grand.c: Updated G_RAND_DOUBLE_TRANSFORM to be more
|
||||
|
@ -1,3 +1,16 @@
|
||||
2000-12-22 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* configure.in: Determine the suffix of the shared librarries for
|
||||
this system. This is done analogous to
|
||||
ltconfig.sh. G_MODULE_SUFFIX in glibconfig.h is set to either
|
||||
"sl", "dll", or (most often) "so".
|
||||
|
||||
* tests/Makefile.am, tests/module-test.c,
|
||||
tests/libmoduletestplugin_a.c, tests/libmoduletestplugin_b.c:
|
||||
Added new testcase for gmodule. This is mostly copied from
|
||||
gmodule/testgmodule.c, but unlike that is is quiet. (Why BTW are
|
||||
some tests that verbose, not to say loquacious...)
|
||||
|
||||
2000-12-19 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* grand.c: Updated G_RAND_DOUBLE_TRANSFORM to be more
|
||||
|
@ -1,3 +1,16 @@
|
||||
2000-12-22 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* configure.in: Determine the suffix of the shared librarries for
|
||||
this system. This is done analogous to
|
||||
ltconfig.sh. G_MODULE_SUFFIX in glibconfig.h is set to either
|
||||
"sl", "dll", or (most often) "so".
|
||||
|
||||
* tests/Makefile.am, tests/module-test.c,
|
||||
tests/libmoduletestplugin_a.c, tests/libmoduletestplugin_b.c:
|
||||
Added new testcase for gmodule. This is mostly copied from
|
||||
gmodule/testgmodule.c, but unlike that is is quiet. (Why BTW are
|
||||
some tests that verbose, not to say loquacious...)
|
||||
|
||||
2000-12-19 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* grand.c: Updated G_RAND_DOUBLE_TRANSFORM to be more
|
||||
|
@ -1,3 +1,16 @@
|
||||
2000-12-22 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* configure.in: Determine the suffix of the shared librarries for
|
||||
this system. This is done analogous to
|
||||
ltconfig.sh. G_MODULE_SUFFIX in glibconfig.h is set to either
|
||||
"sl", "dll", or (most often) "so".
|
||||
|
||||
* tests/Makefile.am, tests/module-test.c,
|
||||
tests/libmoduletestplugin_a.c, tests/libmoduletestplugin_b.c:
|
||||
Added new testcase for gmodule. This is mostly copied from
|
||||
gmodule/testgmodule.c, but unlike that is is quiet. (Why BTW are
|
||||
some tests that verbose, not to say loquacious...)
|
||||
|
||||
2000-12-19 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* grand.c: Updated G_RAND_DOUBLE_TRANSFORM to be more
|
||||
|
@ -1,3 +1,16 @@
|
||||
2000-12-22 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* configure.in: Determine the suffix of the shared librarries for
|
||||
this system. This is done analogous to
|
||||
ltconfig.sh. G_MODULE_SUFFIX in glibconfig.h is set to either
|
||||
"sl", "dll", or (most often) "so".
|
||||
|
||||
* tests/Makefile.am, tests/module-test.c,
|
||||
tests/libmoduletestplugin_a.c, tests/libmoduletestplugin_b.c:
|
||||
Added new testcase for gmodule. This is mostly copied from
|
||||
gmodule/testgmodule.c, but unlike that is is quiet. (Why BTW are
|
||||
some tests that verbose, not to say loquacious...)
|
||||
|
||||
2000-12-19 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* grand.c: Updated G_RAND_DOUBLE_TRANSFORM to be more
|
||||
|
@ -1,3 +1,16 @@
|
||||
2000-12-22 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* configure.in: Determine the suffix of the shared librarries for
|
||||
this system. This is done analogous to
|
||||
ltconfig.sh. G_MODULE_SUFFIX in glibconfig.h is set to either
|
||||
"sl", "dll", or (most often) "so".
|
||||
|
||||
* tests/Makefile.am, tests/module-test.c,
|
||||
tests/libmoduletestplugin_a.c, tests/libmoduletestplugin_b.c:
|
||||
Added new testcase for gmodule. This is mostly copied from
|
||||
gmodule/testgmodule.c, but unlike that is is quiet. (Why BTW are
|
||||
some tests that verbose, not to say loquacious...)
|
||||
|
||||
2000-12-19 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* grand.c: Updated G_RAND_DOUBLE_TRANSFORM to be more
|
||||
|
@ -1,3 +1,16 @@
|
||||
2000-12-22 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* configure.in: Determine the suffix of the shared librarries for
|
||||
this system. This is done analogous to
|
||||
ltconfig.sh. G_MODULE_SUFFIX in glibconfig.h is set to either
|
||||
"sl", "dll", or (most often) "so".
|
||||
|
||||
* tests/Makefile.am, tests/module-test.c,
|
||||
tests/libmoduletestplugin_a.c, tests/libmoduletestplugin_b.c:
|
||||
Added new testcase for gmodule. This is mostly copied from
|
||||
gmodule/testgmodule.c, but unlike that is is quiet. (Why BTW are
|
||||
some tests that verbose, not to say loquacious...)
|
||||
|
||||
2000-12-19 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* grand.c: Updated G_RAND_DOUBLE_TRANSFORM to be more
|
||||
|
@ -1,3 +1,16 @@
|
||||
2000-12-22 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* configure.in: Determine the suffix of the shared librarries for
|
||||
this system. This is done analogous to
|
||||
ltconfig.sh. G_MODULE_SUFFIX in glibconfig.h is set to either
|
||||
"sl", "dll", or (most often) "so".
|
||||
|
||||
* tests/Makefile.am, tests/module-test.c,
|
||||
tests/libmoduletestplugin_a.c, tests/libmoduletestplugin_b.c:
|
||||
Added new testcase for gmodule. This is mostly copied from
|
||||
gmodule/testgmodule.c, but unlike that is is quiet. (Why BTW are
|
||||
some tests that verbose, not to say loquacious...)
|
||||
|
||||
2000-12-19 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* grand.c: Updated G_RAND_DOUBLE_TRANSFORM to be more
|
||||
|
19
configure.in
19
configure.in
@ -680,6 +680,21 @@ dnl *** done, have e got an implementation?
|
||||
if test -z "$G_MODULE_IMPL"; then
|
||||
G_MODULE_IMPL=0
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING(for the suffix of shared libraries)
|
||||
case "$host_os" in
|
||||
hpux9* | hpux10* | hpux11*) # taken from ltconfig
|
||||
glib_gmodule_suffix='sl'
|
||||
;;
|
||||
cygwin* | mingw*)
|
||||
glib_gmodule_suffix='dll'
|
||||
;;
|
||||
*)
|
||||
glib_gmodule_suffix='so'
|
||||
;;
|
||||
esac
|
||||
AC_MSG_RESULT(.$glib_gmodule_suffix)
|
||||
|
||||
AC_SUBST(G_MODULE_IMPL)
|
||||
AC_SUBST(G_MODULE_LIBS)
|
||||
AC_SUBST(G_MODULE_LIBS_EXTRA)
|
||||
@ -1499,6 +1514,8 @@ _______EOF
|
||||
|
||||
cat >>$outfile <<_______EOF
|
||||
|
||||
#define G_MODULE_SUFFIX "$g_module_suffix"
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* GLIBCONFIG_H */
|
||||
@ -1709,6 +1726,8 @@ g_mutex_sizeof="$glib_cv_sizeof_gmutex"
|
||||
g_system_thread_sizeof="$glib_cv_sizeof_system_thread"
|
||||
g_mutex_contents="$glib_cv_byte_contents_gmutex"
|
||||
|
||||
g_module_suffix="$glib_gmodule_suffix"
|
||||
|
||||
case $host in
|
||||
*-*-beos*)
|
||||
glib_os="#define G_OS_BEOS"
|
||||
|
@ -1,3 +1,9 @@
|
||||
2000-12-22 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* glib/glib-sections.txt: Added G_MODULE_SUFFIX.
|
||||
|
||||
* glib/tmpl/modules.sgml: Updated.
|
||||
|
||||
2000-12-19 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* glib/glib-sections.txt: Added g_rand_boolean and
|
||||
|
@ -1094,6 +1094,7 @@ g_module_error
|
||||
<SUBSECTION>
|
||||
GModuleCheckInit
|
||||
GModuleUnload
|
||||
G_MODULE_SUFFIX
|
||||
G_MODULE_EXPORT
|
||||
G_MODULE_IMPORT
|
||||
</SECTION>
|
||||
|
@ -91,8 +91,20 @@ prefix and suffix. This should be freed when no longer needed.
|
||||
|
||||
<!-- ##### FUNCTION g_module_open ##### -->
|
||||
<para>
|
||||
Opens a module.
|
||||
If the module has already been opened, its reference count is incremented.
|
||||
Opens a module. If the module has already been opened, its reference
|
||||
count is incremented.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
First of all g_module_open() tries to open @file_name as a module. If
|
||||
that fails and @file_name has the ".la"-suffix (and is a libtool
|
||||
archive) it tries to open the corresponding module. If that fails and
|
||||
it doesn't have the proper module suffix for that plaform
|
||||
(#G_MODULE_SUFFIX,) this suffix will be appended and the coresponding
|
||||
module will be opended. If that fails and @file_name doesn't have the
|
||||
".la"-suffix, this suffix is appended and g_module_open() tries to
|
||||
open the corresponding module. If eventually that fails as well, NULL
|
||||
is returned.
|
||||
</para>
|
||||
|
||||
@file_name: the name of the file containing the module.
|
||||
@ -183,6 +195,15 @@ It is passed the #GModule structure.
|
||||
@module: the module about to be unloaded.
|
||||
|
||||
|
||||
<!-- ##### MACRO G_MODULE_SUFFIX ##### -->
|
||||
<para>
|
||||
Expands to the proper shared library suffix for the current platform
|
||||
without the leading dot. For the most Unices and Linux this is "so",
|
||||
for some HPUX versions this is "sl" and for Windows this is "dll".
|
||||
</para>
|
||||
|
||||
|
||||
|
||||
<!-- ##### MACRO G_MODULE_EXPORT ##### -->
|
||||
<para>
|
||||
Used to declare functions exported by modules.
|
||||
|
@ -1,3 +1,23 @@
|
||||
2000-12-22 Sebastian Wilhelmi <wilhelmi@ira.uka.de>
|
||||
|
||||
* gmodule.c: Make g_module_open more tolerant wrt to the module
|
||||
name. First it tries to open the module as named, if that fails,
|
||||
it checks, whether it is a libtool archive and parses it, if that
|
||||
fails it appends the systems shared library suffix
|
||||
(i.e. ".so") (if not already found) and tries again and if that
|
||||
fails it tries to append the ".la" libtool suffix (if not already
|
||||
found) and parses it.
|
||||
|
||||
* gmodule.c: Lock recursive mutex during most module functions for
|
||||
safety.
|
||||
|
||||
* gmodule-dl.c: Return an error from _g_module_symbol only, if
|
||||
dlerror says so. All other functions return an error as well, if
|
||||
dlerror returns NULL.
|
||||
|
||||
* testgmodule.c: Thanks to the above change the #ifdefs have
|
||||
vanished.
|
||||
|
||||
2000-10-15 Raja R Harinath <harinath@cs.umn.edu>
|
||||
|
||||
* Makefile.am (BUILT_EXTRA_DIST): New variable.
|
||||
|
@ -71,13 +71,17 @@
|
||||
|
||||
/* --- functions --- */
|
||||
static gchar*
|
||||
fetch_dlerror (void)
|
||||
fetch_dlerror (gboolean replace_null)
|
||||
{
|
||||
gchar *msg = dlerror ();
|
||||
|
||||
/* make sure we always return an error message != NULL */
|
||||
/* make sure we always return an error message != NULL, if
|
||||
* expected to do so. */
|
||||
|
||||
return msg ? msg : "unknown dl-error";
|
||||
if (!msg && replace_null)
|
||||
return "unknown dl-error";
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
@ -88,7 +92,7 @@ _g_module_open (const gchar *file_name,
|
||||
|
||||
handle = dlopen (file_name, RTLD_GLOBAL | (bind_lazy ? RTLD_LAZY : RTLD_NOW));
|
||||
if (!handle)
|
||||
g_module_set_error (fetch_dlerror ());
|
||||
g_module_set_error (fetch_dlerror (TRUE));
|
||||
|
||||
return handle;
|
||||
}
|
||||
@ -104,7 +108,7 @@ _g_module_self (void)
|
||||
|
||||
handle = dlopen (NULL, RTLD_GLOBAL | RTLD_LAZY);
|
||||
if (!handle)
|
||||
g_module_set_error (fetch_dlerror ());
|
||||
g_module_set_error (fetch_dlerror (TRUE));
|
||||
|
||||
return handle;
|
||||
}
|
||||
@ -121,7 +125,7 @@ _g_module_close (gpointer handle,
|
||||
if (is_unref)
|
||||
{
|
||||
if (dlclose (handle) != 0)
|
||||
g_module_set_error (fetch_dlerror ());
|
||||
g_module_set_error (fetch_dlerror (TRUE));
|
||||
}
|
||||
}
|
||||
|
||||
@ -133,7 +137,7 @@ _g_module_symbol (gpointer handle,
|
||||
|
||||
p = dlsym (handle, symbol_name);
|
||||
if (!p)
|
||||
g_module_set_error (fetch_dlerror ());
|
||||
g_module_set_error (fetch_dlerror (FALSE));
|
||||
|
||||
return p;
|
||||
}
|
||||
|
@ -28,11 +28,19 @@
|
||||
* MT safe
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
#include "gmodule.h"
|
||||
#include "gmoduleconf.h"
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
/* We maintain a list of modules, so we can reference count them.
|
||||
* That's needed because some platforms don't support refernce counts on
|
||||
@ -71,7 +79,6 @@ static inline GModule* g_module_find_by_name (const gchar *name);
|
||||
|
||||
|
||||
/* --- variables --- */
|
||||
G_LOCK_DEFINE_STATIC (GModule);
|
||||
const char *g_log_domain_gmodule = "GModule";
|
||||
static GModule *modules = NULL;
|
||||
static GModule *main_module = NULL;
|
||||
@ -85,7 +92,6 @@ g_module_find_by_handle (gpointer handle)
|
||||
GModule *module;
|
||||
GModule *retval = NULL;
|
||||
|
||||
G_LOCK (GModule);
|
||||
if (main_module && main_module->handle == handle)
|
||||
retval = main_module;
|
||||
else
|
||||
@ -95,7 +101,6 @@ g_module_find_by_handle (gpointer handle)
|
||||
retval = module;
|
||||
break;
|
||||
}
|
||||
G_UNLOCK (GModule);
|
||||
|
||||
return retval;
|
||||
}
|
||||
@ -106,14 +111,12 @@ g_module_find_by_name (const gchar *name)
|
||||
GModule *module;
|
||||
GModule *retval = NULL;
|
||||
|
||||
G_LOCK (GModule);
|
||||
for (module = modules; module; module = module->next)
|
||||
if (strcmp (name, module->file_name) == 0)
|
||||
{
|
||||
retval = module;
|
||||
break;
|
||||
}
|
||||
G_UNLOCK (GModule);
|
||||
|
||||
return retval;
|
||||
}
|
||||
@ -177,6 +180,103 @@ g_module_supported (void)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gchar*
|
||||
parse_libtool_archive (const gchar* libtool_name)
|
||||
{
|
||||
const gint TOKEN_DLNAME = G_TOKEN_LAST + 1;
|
||||
const gint TOKEN_INSTALLED = G_TOKEN_LAST + 2;
|
||||
const gint TOKEN_LIBDIR = G_TOKEN_LAST + 3;
|
||||
gchar *lt_dlname = NULL;
|
||||
gboolean lt_installed = TRUE;
|
||||
gchar *lt_libdir = NULL;
|
||||
gchar *name;
|
||||
GTokenType token;
|
||||
GScanner *scanner;
|
||||
|
||||
int fd = open (libtool_name, O_RDONLY, 0);
|
||||
if (fd < 0)
|
||||
{
|
||||
g_module_set_error ("couldn't open libtool archive");
|
||||
return NULL;
|
||||
}
|
||||
/* search libtool's dlname specification */
|
||||
scanner = g_scanner_new (NULL);
|
||||
g_scanner_input_file (scanner, fd);
|
||||
scanner->config->symbol_2_token = TRUE;
|
||||
g_scanner_scope_add_symbol (scanner, 0, "dlname",
|
||||
GUINT_TO_POINTER (TOKEN_DLNAME));
|
||||
g_scanner_scope_add_symbol (scanner, 0, "installed",
|
||||
GUINT_TO_POINTER (TOKEN_INSTALLED));
|
||||
g_scanner_scope_add_symbol (scanner, 0, "libdir",
|
||||
GUINT_TO_POINTER (TOKEN_LIBDIR));
|
||||
while (!g_scanner_eof (scanner))
|
||||
{
|
||||
token = g_scanner_get_next_token (scanner);
|
||||
if (token == TOKEN_DLNAME || token == TOKEN_INSTALLED ||
|
||||
token == TOKEN_LIBDIR)
|
||||
{
|
||||
if (g_scanner_get_next_token (scanner) != '=' ||
|
||||
g_scanner_get_next_token (scanner) !=
|
||||
(token == TOKEN_INSTALLED ?
|
||||
G_TOKEN_IDENTIFIER : G_TOKEN_STRING))
|
||||
{
|
||||
g_module_set_error ("libtool archive has unknown format");
|
||||
|
||||
g_free (lt_dlname);
|
||||
g_free (lt_libdir);
|
||||
g_scanner_destroy (scanner);
|
||||
close (fd);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (token == TOKEN_DLNAME)
|
||||
{
|
||||
g_free (lt_dlname);
|
||||
lt_dlname = g_strdup (scanner->value.v_string);
|
||||
}
|
||||
else if (token == TOKEN_INSTALLED)
|
||||
lt_installed =
|
||||
strcmp (scanner->value.v_identifier, "yes") == 0;
|
||||
else /* token == TOKEN_LIBDIR */
|
||||
{
|
||||
g_free (lt_libdir);
|
||||
lt_libdir = g_strdup (scanner->value.v_string);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!lt_installed)
|
||||
{
|
||||
gchar *dir = g_path_get_dirname (libtool_name);
|
||||
g_free (lt_libdir);
|
||||
lt_libdir = g_strconcat (dir, G_DIR_SEPARATOR_S ".libs", NULL);
|
||||
}
|
||||
|
||||
name = g_module_build_path (lt_libdir, lt_dlname);
|
||||
|
||||
g_free (lt_dlname);
|
||||
g_free (lt_libdir);
|
||||
g_scanner_destroy (scanner);
|
||||
close (fd);
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
static inline gboolean
|
||||
g_str_check_suffix (const gchar* string, const gchar* suffix)
|
||||
{
|
||||
guint string_len = strlen (string);
|
||||
guint suffix_len = strlen (suffix);
|
||||
|
||||
return string_len >= suffix_len &&
|
||||
strcmp (string + string_len - suffix_len, suffix) == 0;
|
||||
}
|
||||
|
||||
static GStaticRecMutex g_module_global_lock = G_STATIC_REC_MUTEX_INIT;
|
||||
|
||||
GModule*
|
||||
g_module_open (const gchar *file_name,
|
||||
GModuleFlags flags)
|
||||
@ -186,9 +286,9 @@ g_module_open (const gchar *file_name,
|
||||
|
||||
SUPPORT_OR_RETURN (NULL);
|
||||
|
||||
g_static_rec_mutex_lock (&g_module_global_lock);
|
||||
if (!file_name)
|
||||
{
|
||||
G_LOCK (GModule);
|
||||
if (!main_module)
|
||||
{
|
||||
handle = _g_module_self ();
|
||||
@ -203,8 +303,8 @@ g_module_open (const gchar *file_name,
|
||||
main_module->next = NULL;
|
||||
}
|
||||
}
|
||||
G_UNLOCK (GModule);
|
||||
|
||||
g_static_rec_mutex_unlock (&g_module_global_lock);
|
||||
return main_module;
|
||||
}
|
||||
|
||||
@ -214,11 +314,46 @@ g_module_open (const gchar *file_name,
|
||||
{
|
||||
module->ref_count++;
|
||||
|
||||
g_static_rec_mutex_unlock (&g_module_global_lock);
|
||||
return module;
|
||||
}
|
||||
|
||||
/* open the module */
|
||||
/* First we try to open the module as provided */
|
||||
handle = _g_module_open (file_name, (flags & G_MODULE_BIND_LAZY) != 0);
|
||||
|
||||
/* If not found, we check, if it is a libtool archive */
|
||||
if (!handle && g_str_check_suffix (file_name, ".la"))
|
||||
{
|
||||
gchar *name = parse_libtool_archive (file_name);
|
||||
if (name)
|
||||
{
|
||||
handle = _g_module_open (name, (flags & G_MODULE_BIND_LAZY) != 0);
|
||||
g_free (name);
|
||||
}
|
||||
}
|
||||
|
||||
/* If still not found, we check, if it is a library name without suffix */
|
||||
if (!handle && !g_str_check_suffix (file_name, "." G_MODULE_SUFFIX))
|
||||
{
|
||||
gchar *name = g_strconcat (file_name, "." G_MODULE_SUFFIX, NULL);
|
||||
handle = _g_module_open (name, (flags & G_MODULE_BIND_LAZY) != 0);
|
||||
g_free (name);
|
||||
}
|
||||
|
||||
/* If still not found, we check, if it is a libtool archive name
|
||||
* without suffix */
|
||||
if (!handle && !g_str_check_suffix (file_name, ".la"))
|
||||
{
|
||||
gchar *la_name = g_strconcat (file_name, ".la", NULL);
|
||||
gchar *name = parse_libtool_archive (la_name);
|
||||
if (name)
|
||||
{
|
||||
handle = _g_module_open (name, (flags & G_MODULE_BIND_LAZY) != 0);
|
||||
g_free (name);
|
||||
}
|
||||
g_free (la_name);
|
||||
}
|
||||
|
||||
if (handle)
|
||||
{
|
||||
gchar *saved_error;
|
||||
@ -233,6 +368,7 @@ g_module_open (const gchar *file_name,
|
||||
module->ref_count++;
|
||||
g_module_set_error (NULL);
|
||||
|
||||
g_static_rec_mutex_unlock (&g_module_global_lock);
|
||||
return module;
|
||||
}
|
||||
|
||||
@ -245,10 +381,8 @@ g_module_open (const gchar *file_name,
|
||||
module->ref_count = 1;
|
||||
module->is_resident = FALSE;
|
||||
module->unload = NULL;
|
||||
G_LOCK (GModule);
|
||||
module->next = modules;
|
||||
modules = module;
|
||||
G_UNLOCK (GModule);
|
||||
|
||||
/* check initialization */
|
||||
if (g_module_symbol (module, "g_module_check_init", (gpointer) &check_init))
|
||||
@ -273,7 +407,8 @@ g_module_open (const gchar *file_name,
|
||||
|
||||
g_free (saved_error);
|
||||
}
|
||||
|
||||
|
||||
g_static_rec_mutex_unlock (&g_module_global_lock);
|
||||
return module;
|
||||
}
|
||||
|
||||
@ -285,6 +420,8 @@ g_module_close (GModule *module)
|
||||
g_return_val_if_fail (module != NULL, FALSE);
|
||||
g_return_val_if_fail (module->ref_count > 0, FALSE);
|
||||
|
||||
g_static_rec_mutex_lock (&g_module_global_lock);
|
||||
|
||||
module->ref_count--;
|
||||
|
||||
if (!module->ref_count && !module->is_resident && module->unload)
|
||||
@ -303,7 +440,6 @@ g_module_close (GModule *module)
|
||||
|
||||
last = NULL;
|
||||
|
||||
G_LOCK (GModule);
|
||||
node = modules;
|
||||
while (node)
|
||||
{
|
||||
@ -319,7 +455,6 @@ g_module_close (GModule *module)
|
||||
node = last->next;
|
||||
}
|
||||
module->next = NULL;
|
||||
G_UNLOCK (GModule);
|
||||
|
||||
_g_module_close (module->handle, FALSE);
|
||||
g_free (module->file_name);
|
||||
@ -327,6 +462,7 @@ g_module_close (GModule *module)
|
||||
g_free (module);
|
||||
}
|
||||
|
||||
g_static_rec_mutex_unlock (&g_module_global_lock);
|
||||
return g_module_error() == NULL;
|
||||
}
|
||||
|
||||
@ -359,6 +495,8 @@ g_module_symbol (GModule *module,
|
||||
g_return_val_if_fail (symbol_name != NULL, FALSE);
|
||||
g_return_val_if_fail (symbol != NULL, FALSE);
|
||||
|
||||
g_static_rec_mutex_lock (&g_module_global_lock);
|
||||
|
||||
#ifdef G_MODULE_NEED_USCORE
|
||||
{
|
||||
gchar *name;
|
||||
@ -380,11 +518,10 @@ g_module_symbol (GModule *module,
|
||||
g_module_set_error (error);
|
||||
g_free (error);
|
||||
*symbol = NULL;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
g_static_rec_mutex_unlock (&g_module_global_lock);
|
||||
return !module_error;
|
||||
}
|
||||
|
||||
gchar*
|
||||
|
@ -54,16 +54,9 @@ main (int arg,
|
||||
string = g_get_current_dir ();
|
||||
g_print ("testgmodule (%s):\n", string);
|
||||
|
||||
#if (G_MODULE_IMPL == G_MODULE_IMPL_WIN32)
|
||||
plugin_a = g_strconcat (string, "\\libgplugin_a.dll", NULL);
|
||||
plugin_b = g_strconcat (string, "\\libgplugin_b.dll", NULL);
|
||||
#elif (G_MODULE_IMPL == G_MODULE_IMPL_DLD)
|
||||
plugin_a = g_strconcat (string, "/.libs/", "libgplugin_a.sl", NULL);
|
||||
plugin_b = g_strconcat (string, "/.libs/", "libgplugin_b.sl", NULL);
|
||||
#else /* neither DLD nor WIN32 */
|
||||
plugin_a = g_strconcat (string, "/.libs/", "libgplugin_a.so", NULL);
|
||||
plugin_b = g_strconcat (string, "/.libs/", "libgplugin_b.so", NULL);
|
||||
#endif
|
||||
plugin_a = g_strconcat (string, G_DIR_SEPARATOR_S "libgplugin_a", NULL);
|
||||
plugin_b = g_strconcat (string, G_DIR_SEPARATOR_S "libgplugin_b", NULL);
|
||||
|
||||
g_free (string);
|
||||
|
||||
/* module handles
|
||||
|
@ -6,6 +6,8 @@ Makefile.in
|
||||
makefile.msc
|
||||
makefile.mingw
|
||||
_libs
|
||||
libmoduletestplugin_a.la
|
||||
libmoduletestplugin_b.la
|
||||
array-test
|
||||
date-test
|
||||
dirname-test
|
||||
@ -13,6 +15,7 @@ hash-test
|
||||
list-test
|
||||
mainloop-test
|
||||
markup-test
|
||||
module-test
|
||||
node-test
|
||||
queue-test
|
||||
rand-test
|
||||
|
@ -20,6 +20,7 @@ test_programs = \
|
||||
hash-test \
|
||||
list-test \
|
||||
mainloop-test \
|
||||
module-test \
|
||||
node-test \
|
||||
queue-test \
|
||||
rand-test \
|
||||
@ -45,6 +46,7 @@ TESTS_ENVIRONMENT = srcdir=$(srcdir)
|
||||
|
||||
progs_LDADD = $(EFENCE) $(top_builddir)/libglib-1.3.la $(EFENCE)
|
||||
thread_LDADD = $(progs_LDADD) $(top_builddir)/gthread/libgthread-1.3.la @G_THREAD_LIBS@
|
||||
module_LDADD = $(progs_LDADD) $(top_builddir)/gmodule/libgmodule-1.3.la @G_MODULE_LIBS@
|
||||
|
||||
array_test_LDADD = $(progs_LDADD)
|
||||
date_test_LDADD = $(progs_LDADD)
|
||||
@ -54,6 +56,8 @@ hash_test_LDADD = $(progs_LDADD)
|
||||
list_test_LDADD = $(progs_LDADD)
|
||||
mainloop_test_LDADD = $(thread_LDADD)
|
||||
markup_test_LDADD = $(progs_LDADD)
|
||||
module_test_LDADD = $(module_LDADD)
|
||||
module_test_LDFLAGS = @G_MODULE_LDFLAGS@
|
||||
node_test_LDADD = $(progs_LDADD)
|
||||
queue_test_LDADD = $(progs_LDADD)
|
||||
rand_test_LDADD = $(progs_LDADD)
|
||||
@ -68,6 +72,20 @@ threadpool_test_LDADD = $(thread_LDADD)
|
||||
tree_test_LDADD = $(progs_LDADD)
|
||||
type_test_LDADD = $(progs_LDADD)
|
||||
|
||||
lib_LTLIBRARIES = libmoduletestplugin_a.la libmoduletestplugin_b.la
|
||||
|
||||
# Prevent those libs from being installed
|
||||
install-libLTLIBRARIES:
|
||||
:
|
||||
|
||||
libmoduletestplugin_a_la_SOURCES = libmoduletestplugin_a.c
|
||||
libmoduletestplugin_a_la_LDFLAGS = @G_MODULE_LDFLAGS@ -avoid-version -module
|
||||
libmoduletestplugin_a_la_LIBADD = @G_MODULE_LIBS@
|
||||
|
||||
libmoduletestplugin_b_la_SOURCES = libmoduletestplugin_b.c
|
||||
libmoduletestplugin_b_la_LDFLAGS = @G_MODULE_LDFLAGS@ -avoid-version -module
|
||||
libmoduletestplugin_b_la_LIBADD = @G_MODULE_LIBS@
|
||||
|
||||
makefile.msc: $(top_builddir)/config.status $(top_srcdir)/tests/makefile.msc.in
|
||||
cd $(top_builddir) && CONFIG_FILES=tests/$@ CONFIG_HEADERS= $(SHELL) ./config.status
|
||||
|
||||
|
68
tests/libmoduletestplugin_a.c
Normal file
68
tests/libmoduletestplugin_a.c
Normal file
@ -0,0 +1,68 @@
|
||||
/* libgplugin_a.c - test plugin for testgmodule
|
||||
* Copyright (C) 1998 Tim Janik
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
|
||||
* file for a list of people on the GLib Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GLib at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
#include <gmodule.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
G_MODULE_EXPORT gchar* gplugin_a_state;
|
||||
|
||||
G_MODULE_EXPORT void
|
||||
gplugin_a_func (void)
|
||||
{
|
||||
gplugin_a_state = "Hello world";
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT void
|
||||
gplugin_clash_func (void)
|
||||
{
|
||||
gplugin_a_state = "plugin clash";
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT void
|
||||
g_clash_func (void)
|
||||
{
|
||||
gplugin_a_state = "global clash";
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT void
|
||||
gplugin_say_boo_func (void)
|
||||
{
|
||||
gplugin_a_state = "BOOH";
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT void
|
||||
gplugin_a_module_func (GModule *module)
|
||||
{
|
||||
void (*f) (void) = NULL;
|
||||
|
||||
if (!g_module_symbol (module, "gplugin_say_boo_func", (gpointer) &f))
|
||||
{
|
||||
g_print ("error: %s\n", g_module_error ());
|
||||
exit (1);
|
||||
}
|
||||
|
||||
f ();
|
||||
}
|
67
tests/libmoduletestplugin_b.c
Normal file
67
tests/libmoduletestplugin_b.c
Normal file
@ -0,0 +1,67 @@
|
||||
/* libgplugin_b.c - test plugin for testgmodule
|
||||
* Copyright (C) 1998 Tim Janik
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
|
||||
* file for a list of people on the GLib Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GLib at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
#include <gmodule.h>
|
||||
|
||||
G_MODULE_EXPORT gchar* gplugin_b_state;
|
||||
|
||||
G_MODULE_EXPORT const gchar*
|
||||
g_module_check_init (GModule *module)
|
||||
{
|
||||
gplugin_b_state = "check-init";
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT void
|
||||
g_module_unload (GModule *module)
|
||||
{
|
||||
gplugin_b_state = "unloaded";
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT void
|
||||
gplugin_b_func (void)
|
||||
{
|
||||
gplugin_b_state = "Hello world";
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT void
|
||||
gplugin_clash_func (void)
|
||||
{
|
||||
gplugin_b_state = "plugin clash";
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT void
|
||||
g_clash_func (void)
|
||||
{
|
||||
gplugin_b_state = "global clash";
|
||||
}
|
||||
|
||||
G_MODULE_EXPORT void
|
||||
gplugin_say_boo_func (void)
|
||||
{
|
||||
gplugin_b_state = "BOOH";
|
||||
}
|
198
tests/module-test.c
Normal file
198
tests/module-test.c
Normal file
@ -0,0 +1,198 @@
|
||||
/* module-test.c - test program for GMODULE
|
||||
* Copyright (C) 1998 Tim Janik
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Modified by the GLib Team and others 1997-2000. See the AUTHORS
|
||||
* file for a list of people on the GLib Team. See the ChangeLog
|
||||
* files for a list of changes. These files are distributed with
|
||||
* GLib at ftp://ftp.gtk.org/pub/gtk/.
|
||||
*/
|
||||
|
||||
#include <gmodule.h>
|
||||
|
||||
gchar* global_state;
|
||||
|
||||
G_MODULE_EXPORT void
|
||||
g_clash_func (void)
|
||||
{
|
||||
global_state = "global clash";
|
||||
}
|
||||
|
||||
typedef void (*SimpleFunc) (void);
|
||||
typedef void (*GModuleFunc) (GModule *);
|
||||
|
||||
static gchar **gplugin_a_state;
|
||||
static gchar **gplugin_b_state;
|
||||
|
||||
static void
|
||||
compare (const gchar *desc, const gchar *expected, const gchar *found)
|
||||
{
|
||||
if (!expected && !found)
|
||||
return;
|
||||
|
||||
if (expected && found && strcmp (expected, found) == 0)
|
||||
return;
|
||||
|
||||
g_error ("error: %s state should have been \"%s\", but is \"%s\"",
|
||||
desc, expected ? expected : "NULL", found ? found : "NULL");
|
||||
}
|
||||
|
||||
static void
|
||||
test_states (const gchar *global, const gchar *gplugin_a,
|
||||
const gchar *gplugin_b)
|
||||
{
|
||||
compare ("global", global, global_state);
|
||||
compare ("Plugin A", gplugin_a, *gplugin_a_state);
|
||||
compare ("Plugin B", gplugin_b, *gplugin_b_state);
|
||||
|
||||
global_state = *gplugin_a_state = *gplugin_b_state = NULL;
|
||||
}
|
||||
|
||||
static SimpleFunc plugin_clash_func = NULL;
|
||||
|
||||
int
|
||||
main (int arg,
|
||||
char *argv[])
|
||||
{
|
||||
GModule *module_self, *module_a, *module_b;
|
||||
gchar *dir;
|
||||
gchar *plugin_a, *plugin_b;
|
||||
SimpleFunc f_a, f_b, f_self;
|
||||
GModuleFunc gmod_f;
|
||||
|
||||
if (!g_module_supported ())
|
||||
return 0;
|
||||
|
||||
dir = g_get_current_dir ();
|
||||
|
||||
plugin_a = g_strconcat (dir, G_DIR_SEPARATOR_S "libmoduletestplugin_a",
|
||||
NULL);
|
||||
plugin_b = g_strconcat (dir, G_DIR_SEPARATOR_S "libmoduletestplugin_b",
|
||||
NULL);
|
||||
|
||||
g_free (dir);
|
||||
|
||||
/* module handles */
|
||||
|
||||
module_self = g_module_open (NULL, G_MODULE_BIND_LAZY);
|
||||
if (!module_self)
|
||||
g_error ("error: %s", g_module_error ());
|
||||
|
||||
if (!g_module_symbol (module_self, "g_module_close", (gpointer) &f_self))
|
||||
g_error ("error: %s", g_module_error ());
|
||||
|
||||
module_a = g_module_open (plugin_a, G_MODULE_BIND_LAZY);
|
||||
if (!module_a)
|
||||
g_error ("error: %s", g_module_error ());
|
||||
|
||||
module_b = g_module_open (plugin_b, G_MODULE_BIND_LAZY);
|
||||
if (!module_b)
|
||||
g_error ("error: %s", g_module_error ());
|
||||
|
||||
/* get plugin state vars */
|
||||
|
||||
if (!g_module_symbol (module_a, "gplugin_a_state",
|
||||
(gpointer) &gplugin_a_state))
|
||||
g_error ("error: %s", g_module_error ());
|
||||
|
||||
if (!g_module_symbol (module_b, "gplugin_b_state",
|
||||
(gpointer) &gplugin_b_state))
|
||||
g_error ("error: %s", g_module_error ());
|
||||
test_states (NULL, NULL, "check-init");
|
||||
|
||||
/* get plugin specific symbols and call them
|
||||
*/
|
||||
if (!g_module_symbol (module_a, "gplugin_a_func", (gpointer) &f_a))
|
||||
g_error ("error: %s", g_module_error ());
|
||||
test_states (NULL, NULL, NULL);
|
||||
|
||||
if (!g_module_symbol (module_b, "gplugin_b_func", (gpointer) &f_b))
|
||||
g_error ("error: %s", g_module_error ());
|
||||
test_states (NULL, NULL, NULL);
|
||||
|
||||
f_a ();
|
||||
test_states (NULL, "Hello world", NULL);
|
||||
|
||||
f_b ();
|
||||
test_states (NULL, NULL, "Hello world");
|
||||
|
||||
/* get and call globally clashing functions
|
||||
*/
|
||||
|
||||
if (!g_module_symbol (module_self, "g_clash_func", (gpointer) &f_self))
|
||||
g_error ("error: %s", g_module_error ());
|
||||
test_states (NULL, NULL, NULL);
|
||||
|
||||
if (!g_module_symbol (module_a, "g_clash_func", (gpointer) &f_a))
|
||||
g_error ("error: %s", g_module_error ());
|
||||
test_states (NULL, NULL, NULL);
|
||||
|
||||
if (!g_module_symbol (module_b, "g_clash_func", (gpointer) &f_b))
|
||||
g_error ("error: %s", g_module_error ());
|
||||
test_states (NULL, NULL, NULL);
|
||||
|
||||
f_self ();
|
||||
test_states ("global clash", NULL, NULL);
|
||||
|
||||
f_a ();
|
||||
test_states (NULL, "global clash", NULL);
|
||||
|
||||
f_b ();
|
||||
test_states (NULL, NULL, "global clash");
|
||||
|
||||
/* get and call clashing plugin functions */
|
||||
|
||||
if (!g_module_symbol (module_a, "gplugin_clash_func", (gpointer) &f_a))
|
||||
g_error ("error: %s", g_module_error ());
|
||||
test_states (NULL, NULL, NULL);
|
||||
|
||||
if (!g_module_symbol (module_b, "gplugin_clash_func", (gpointer) &f_b))
|
||||
g_error ("error: %s", g_module_error ());
|
||||
test_states (NULL, NULL, NULL);
|
||||
|
||||
plugin_clash_func = f_a;
|
||||
plugin_clash_func ();
|
||||
test_states (NULL, "plugin clash", NULL);
|
||||
|
||||
plugin_clash_func = f_b;
|
||||
plugin_clash_func ();
|
||||
test_states (NULL, NULL, "plugin clash");
|
||||
|
||||
/* call gmodule function from A */
|
||||
|
||||
if (!g_module_symbol (module_a, "gplugin_a_module_func", (gpointer) &gmod_f))
|
||||
g_error ("error: %s", g_module_error ());
|
||||
test_states (NULL, NULL, NULL);
|
||||
|
||||
gmod_f (module_b);
|
||||
test_states (NULL, NULL, "BOOH");
|
||||
|
||||
gmod_f (module_a);
|
||||
test_states (NULL, "BOOH", NULL);
|
||||
|
||||
/* unload plugins */
|
||||
|
||||
if (!g_module_close (module_a))
|
||||
g_error ("error: %s", g_module_error ());
|
||||
|
||||
if (!g_module_close (module_b))
|
||||
g_error ("error: %s", g_module_error ());
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user