From 67c77e22564fbd9cf4543ff939495b3259b3818c Mon Sep 17 00:00:00 2001 From: Eric Blossom Date: Fri, 10 Dec 2010 16:12:04 -0800 Subject: Add new Guile gsubr that loads shared libraries using the equivalent of the RTLD_GLOBAL flag. This is part of a work-around for swig bug: 1863647 http://sourceforge.net/tracker/index.php?func=detail&aid=1863647&group_id=1645&atid=101645 --- gnuradio-core/src/guile/dynl-global.c | 92 +++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 gnuradio-core/src/guile/dynl-global.c (limited to 'gnuradio-core/src/guile/dynl-global.c') diff --git a/gnuradio-core/src/guile/dynl-global.c b/gnuradio-core/src/guile/dynl-global.c new file mode 100644 index 000000000..1fc3a97a5 --- /dev/null +++ b/gnuradio-core/src/guile/dynl-global.c @@ -0,0 +1,92 @@ +/* -*- c -*- */ +/* + * Copyright 2010 Free Software Foundation, Inc. + * + * This file is part of GNU Radio + * + * GNU Radio is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3, or (at your option) + * any later version. + * + * GNU Radio 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +extern scm_t_bits scm_tc16_dynamic_obj; + +static lt_dlhandle +dlopenext_global (const char *filename) +{ + lt_dlhandle handle = 0; + lt_dladvise advise; + + if (!lt_dladvise_init (&advise) + && !lt_dladvise_ext (&advise) + && !lt_dladvise_global(&advise)) + handle = lt_dlopenadvise (filename, advise); + + lt_dladvise_destroy (&advise); + return handle; +} + + +static void * +sysdep_dynl_link_global (const char *fname, const char *subr) +{ + lt_dlhandle handle; + handle = dlopenext_global (fname); + if (NULL == handle) + { + SCM fn; + SCM msg; + + fn = scm_from_locale_string (fname); + msg = scm_from_locale_string (lt_dlerror ()); + scm_misc_error (subr, "file: ~S, message: ~S", scm_list_2 (fn, msg)); + } + return (void *) handle; +} + +SCM_DEFINE (scm_dynamic_link_global, "dynamic-link-global", 1, 0, 0, + (SCM filename), + "Find the shared object (shared library) denoted by\n" + "@var{filename} and link it into the running Guile\n" + "application. The returned\n" + "scheme object is a ``handle'' for the library which can\n" + "be passed to @code{dynamic-func}, @code{dynamic-call} etc.\n\n" + "Searching for object files is system dependent. Normally,\n" + "if @var{filename} does have an explicit directory it will\n" + "be searched for in locations\n" + "such as @file{/usr/lib} and @file{/usr/local/lib}.") +#define FUNC_NAME s_scm_dynamic_link_global +{ + void *handle; + char *file; + + scm_dynwind_begin (0); + file = scm_to_locale_string (filename); + scm_dynwind_free (file); + handle = sysdep_dynl_link_global (file, FUNC_NAME); + scm_dynwind_end (); + SCM_RETURN_NEWSMOB2 (scm_tc16_dynamic_obj, SCM_UNPACK (filename), handle); +} +#undef FUNC_NAME + +void +scm_init_gnuradio_dynl_global_module(void) +{ + scm_c_define_gsubr (s_scm_dynamic_link_global, 1, 0, 0, (SCM (*)()) scm_dynamic_link_global); +} -- cgit From 272971a25cbd777634331a8777d2fbab2bb10ab7 Mon Sep 17 00:00:00 2001 From: Eric Blossom Date: Wed, 22 Dec 2010 16:49:05 -0800 Subject: Check for lt_dladvise_global and fall back to using lt_dlopenext if not found. --- gnuradio-core/src/guile/dynl-global.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'gnuradio-core/src/guile/dynl-global.c') diff --git a/gnuradio-core/src/guile/dynl-global.c b/gnuradio-core/src/guile/dynl-global.c index 1fc3a97a5..3bf2741b1 100644 --- a/gnuradio-core/src/guile/dynl-global.c +++ b/gnuradio-core/src/guile/dynl-global.c @@ -18,6 +18,21 @@ * along with this program. If not, see . */ +/* + * This file is an attempt to work around a problem that appears on + * certain Ubuntu (and perhaps other) systems. On those systems + * (10.04 is known to have the problem, while 10.10 and later work OK + * without this kludge), we end up with a situation where exceptions + * are not caught by the swig code, even though the swig generated + * code "looks right" and "is right". Details of the issue can be + * found in swig bug 1863647, + * http://sourceforge.net/tracker/index.php?func=detail&aid=1863647&group_id=1645&atid=101645 + * + * We work around the problem by loading swig generated guile modules + * using the equivalent of the dlopen's RTLD_GLOBAL flag. This is + * only possible on systems using libtool-2.*. Those systems contain + * the lt_dlavise_global function. + */ #ifdef HAVE_CONFIG_H #include #endif @@ -27,6 +42,10 @@ extern scm_t_bits scm_tc16_dynamic_obj; +#ifdef HAVE_LT_DLADVISE_GLOBAL +/* + * Load shared module using the equivalent of the RTLD_GLOBAL flag + */ static lt_dlhandle dlopenext_global (const char *filename) { @@ -42,6 +61,18 @@ dlopenext_global (const char *filename) return handle; } +#else + +/* + * We don't have lt_dladvise_global. Fall back to lt_dlopenext. + */ +static lt_dlhandle +dlopenext_global (const char *filename) +{ + return lt_dlopenext (filename); +} +#endif + static void * sysdep_dynl_link_global (const char *fname, const char *subr) -- cgit