diff options
author | Tim Janik <timj@src.gnome.org> | 1998-08-09 08:32:18 +0000 |
---|---|---|
committer | Tim Janik <timj@src.gnome.org> | 1998-08-09 08:32:18 +0000 |
commit | db5918bf8e6707b66c175e73635937e65d91357e (patch) | |
tree | 1883d74f9ce85195fb1d49deb4041f4ae70f6442 /gmodule/gmodule-dl.c | |
parent | df6a9afd731bf1e5d55992840222807cb831a96e (diff) |
initial import of gmodule.
Diffstat (limited to 'gmodule/gmodule-dl.c')
-rw-r--r-- | gmodule/gmodule-dl.c | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/gmodule/gmodule-dl.c b/gmodule/gmodule-dl.c new file mode 100644 index 000000000..09d4bd512 --- /dev/null +++ b/gmodule/gmodule-dl.c @@ -0,0 +1,108 @@ +/* GMODULE - GLIB wrapper code for dynamic module loading + * Copyright (C) 1998 Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library 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 + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library 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. + */ +#include <dlfcn.h> + +/* Perl includes <nlist.h> and <link.h> instead of <dlfcn.h> on some systmes? */ + + +/* dlerror() is not implemented on all systems + */ +#ifndef G_MODULE_HAVE_DLERROR +# ifdef __NetBSD__ +# define dlerror() g_strerror (errno) +# else /* !__NetBSD__ */ +/* could we rely on errno's state here? */ +# define dlerror() "unknown dl-error" +# endif /* !__NetBSD__ */ +#endif /* G_MODULE_HAVE_DLERROR */ + +/* some flags are missing on some systems, so we provide + * harmless defaults. + * The Perl sources say, RTLD_LAZY needs to be defined as (1), + * at least for Solaris 1. + */ +#ifndef RTLD_GLOBAL +#define RTLD_GLOBAL 0 +#endif /* RTLD_GLOBAL */ +#ifndef RTLD_LAZY +#define RTLD_LAZY 1 +#endif /* RTLD_LAZY */ +#ifndef RTLD_NOW +#define RTLD_NOW 0 +#endif /* RTLD_NOW */ + + +/* --- functions --- */ +static gpointer +_g_module_open (const gchar *file_name, + 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; +} + +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) +{ + /* 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) + g_module_set_error (dlerror ()); + } +} + +static gpointer +_g_module_symbol (gpointer *handle_p, + const gchar *symbol_name) +{ + gpointer p; + + p = dlsym (*handle_p, symbol_name); + if (!p) + g_module_set_error (dlerror ()); + + return p; +} |