diff --git a/ChangeLog b/ChangeLog index 5dcb47184..51ac6a674 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Sun Feb 22 02:32:14 2004 Matthias Clasen + + * configure.in: Set the gmodule suffix to 'a' for aix and + use the aix gmodule implementation. (#85930, Laurent Vivier) + Sun Feb 22 00:47:04 2004 Matthias Clasen * glib/gnode.c (g_node_copy_deep): New function to deep-copy a diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 5dcb47184..51ac6a674 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,8 @@ +Sun Feb 22 02:32:14 2004 Matthias Clasen + + * configure.in: Set the gmodule suffix to 'a' for aix and + use the aix gmodule implementation. (#85930, Laurent Vivier) + Sun Feb 22 00:47:04 2004 Matthias Clasen * glib/gnode.c (g_node_copy_deep): New function to deep-copy a diff --git a/ChangeLog.pre-2-12 b/ChangeLog.pre-2-12 index 5dcb47184..51ac6a674 100644 --- a/ChangeLog.pre-2-12 +++ b/ChangeLog.pre-2-12 @@ -1,3 +1,8 @@ +Sun Feb 22 02:32:14 2004 Matthias Clasen + + * configure.in: Set the gmodule suffix to 'a' for aix and + use the aix gmodule implementation. (#85930, Laurent Vivier) + Sun Feb 22 00:47:04 2004 Matthias Clasen * glib/gnode.c (g_node_copy_deep): New function to deep-copy a diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 5dcb47184..51ac6a674 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,8 @@ +Sun Feb 22 02:32:14 2004 Matthias Clasen + + * configure.in: Set the gmodule suffix to 'a' for aix and + use the aix gmodule implementation. (#85930, Laurent Vivier) + Sun Feb 22 00:47:04 2004 Matthias Clasen * glib/gnode.c (g_node_copy_deep): New function to deep-copy a diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 5dcb47184..51ac6a674 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,8 @@ +Sun Feb 22 02:32:14 2004 Matthias Clasen + + * configure.in: Set the gmodule suffix to 'a' for aix and + use the aix gmodule implementation. (#85930, Laurent Vivier) + Sun Feb 22 00:47:04 2004 Matthias Clasen * glib/gnode.c (g_node_copy_deep): New function to deep-copy a diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 5dcb47184..51ac6a674 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,8 @@ +Sun Feb 22 02:32:14 2004 Matthias Clasen + + * configure.in: Set the gmodule suffix to 'a' for aix and + use the aix gmodule implementation. (#85930, Laurent Vivier) + Sun Feb 22 00:47:04 2004 Matthias Clasen * glib/gnode.c (g_node_copy_deep): New function to deep-copy a diff --git a/configure.in b/configure.in index 79f5e956a..1328259a6 100644 --- a/configure.in +++ b/configure.in @@ -1007,6 +1007,13 @@ if test -z "$G_MODULE_IMPL"; then *-*-mingw*|*-*-cygwin*) G_MODULE_IMPL=G_MODULE_IMPL_WIN32 ;; esac fi +dnl *** force native AIX library loader +dnl *** dlopen() filepath must be of the form /path/libname.a(libname.so) +if test -z "$G_MODULE_IMPL"; then + case "$host" in + *-*-aix*) G_MODULE_IMPL=G_MODULE_IMPL_AR ;; + esac +fi dnl *** dlopen() and dlsym() in system libraries if test -z "$G_MODULE_IMPL"; then AC_CHECK_FUNC(dlopen, @@ -1129,6 +1136,9 @@ case "$host_os" in cygwin* | mingw*) glib_gmodule_suffix='dll' ;; + aix*) + glib_gmodule_suffix='a' + ;; *) glib_gmodule_suffix='so' ;; diff --git a/gmodule/ChangeLog b/gmodule/ChangeLog index 37a87a785..7f67414f6 100644 --- a/gmodule/ChangeLog +++ b/gmodule/ChangeLog @@ -1,3 +1,11 @@ +Sun Feb 22 02:28:43 2004 Matthias Clasen + + Bug #85930, Laurent Vivier: + + * gmodule-ar.c: Implementation of native module management for AIX. + * gmoduleconf.h.in: + * gmodule.c: Support gmodule-ar.c + 2003-01-01 Tor Lillqvist * gmodule-win32.c (_g_module_build_path): Use g_ascii_strcasecmp(). diff --git a/gmodule/gmodule-ar.c b/gmodule/gmodule-ar.c new file mode 100644 index 000000000..517679412 --- /dev/null +++ b/gmodule/gmodule-ar.c @@ -0,0 +1,181 @@ +/* GMODULE - GLIB wrapper code for dynamic module loading + * Copyright (C) 1998, 2000 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. + */ + +/* + * MT safe + */ + +/* because we are compatible with archive format only since AIX 4.3 */ + +#define __AR_BIG__ +#include + +#include + +/* --- functions --- */ +static gchar* +fetch_dlerror (gboolean replace_null) +{ + gchar *msg = dlerror (); + + /* make sure we always return an error message != NULL, if + * expected to do so. */ + + if (!msg && replace_null) + return "unknown dl-error"; + + return msg; +} + +static gchar* _g_module_get_member(const gchar* file_name) +{ + gchar* member = NULL; + struct fl_hdr file_header; + struct ar_hdr ar_header; + long first_member; + long name_len; + int fd; + + fd = open(file_name, O_RDONLY); + if (fd == -1) + return NULL; + + if (read(fd, (void*)&file_header, FL_HSZ) != FL_HSZ) + goto exit; + + if (strncmp(file_header.fl_magic, AIAMAGBIG, SAIAMAG) != 0) + goto exit; + + /* read first archive file member header */ + + first_member = atol(file_header.fl_fstmoff); + + if (lseek(fd, first_member, SEEK_SET) != first_member) + goto exit; + + if (read(fd, (void*)&ar_header, AR_HSZ - 2) != AR_HSZ - 2) + goto exit; + + /* read member name */ + + name_len = atol(ar_header.ar_namlen); + + member = g_malloc(name_len+1); + if (!member) + goto exit; + + if (read(fd, (void*)member, name_len) != name_len) + { + g_free(member); + member = NULL; + goto exit; + } + + member[name_len] = 0; + +exit: + close(fd); + + return member; +} + +static gpointer +_g_module_open (const gchar *file_name, + gboolean bind_lazy) +{ + gpointer handle; + gchar* member; + gchar* full_name; + + /* extract name of first member of archive */ + + member = _g_module_get_member(file_name); + if (member != NULL) + { + full_name = g_strconcat(file_name, "(", member, ")", NULL); + g_free(member); + } + else + full_name = g_strdup(file_name); + + handle = dlopen (full_name, RTLD_GLOBAL | RTLD_MEMBER | (bind_lazy ? RTLD_LAZY : RTLD_NOW)); + + g_free(full_name); + + if (!handle) + g_module_set_error (fetch_dlerror (TRUE)); + + return handle; +} + +static gpointer +_g_module_self (void) +{ + gpointer handle; + + handle = dlopen (NULL, RTLD_GLOBAL | RTLD_LAZY); + if (!handle) + g_module_set_error (fetch_dlerror (TRUE)); + + return handle; +} + +static void +_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) != 0) + g_module_set_error (fetch_dlerror (TRUE)); + } +} + +static gpointer +_g_module_symbol (gpointer handle, + const gchar *symbol_name) +{ + gpointer p; + + p = dlsym (handle, symbol_name); + if (!p) + g_module_set_error (fetch_dlerror (FALSE)); + + return p; +} + +static gchar* +_g_module_build_path (const gchar *directory, + const gchar *module_name) +{ + if (directory && *directory) { + if (strncmp (module_name, "lib", 3) == 0) + return g_strconcat (directory, "/", module_name, NULL); + else + return g_strconcat (directory, "/lib", module_name, "." G_MODULE_SUFFIX, NULL); + } else if (strncmp (module_name, "lib", 3) == 0) + return g_strdup (module_name); + else + return g_strconcat ("lib", module_name, "." G_MODULE_SUFFIX, NULL); +} diff --git a/gmodule/gmodule.c b/gmodule/gmodule.c index 1429a3283..507f527b0 100644 --- a/gmodule/gmodule.c +++ b/gmodule/gmodule.c @@ -148,6 +148,8 @@ g_module_set_error (const gchar *error) #include "gmodule-win32.c" #elif (G_MODULE_IMPL == G_MODULE_IMPL_DYLD) #include "gmodule-dyld.c" +#elif (G_MODULE_IMPL == G_MODULE_IMPL_AR) +#include "gmodule-ar.c" #else #undef SUPPORT_OR_RETURN #define SUPPORT_OR_RETURN(rv) { g_module_set_error ("dynamic modules are " \ diff --git a/gmodule/gmoduleconf.h.in b/gmodule/gmoduleconf.h.in index a8921d8af..168cf23d2 100644 --- a/gmodule/gmoduleconf.h.in +++ b/gmodule/gmoduleconf.h.in @@ -32,6 +32,7 @@ extern "C" { #define G_MODULE_IMPL_OS2 4 #define G_MODULE_IMPL_BEOS 5 #define G_MODULE_IMPL_DYLD 6 +#define G_MODULE_IMPL_AR 7 #define G_MODULE_IMPL @G_MODULE_IMPL@ #undef G_MODULE_HAVE_DLERROR