summaryrefslogtreecommitdiff
path: root/gnuradio-core/src/guile/dynl-global.c
diff options
context:
space:
mode:
authorJohnathan Corgan2011-03-16 08:18:30 -0700
committerJohnathan Corgan2011-03-16 08:18:30 -0700
commit4cd06fadac972d4cac559c15488bc39823063afe (patch)
tree6fe57896bc216d8c9e672194f2e4e0e75aedb645 /gnuradio-core/src/guile/dynl-global.c
parent4ad736e21f45f64fd616bb53f54e45e1c63e7330 (diff)
parent1d70ed2bd928d52a383e688949cc7f747dd584fa (diff)
downloadgnuradio-4cd06fadac972d4cac559c15488bc39823063afe.tar.gz
gnuradio-4cd06fadac972d4cac559c15488bc39823063afe.tar.bz2
gnuradio-4cd06fadac972d4cac559c15488bc39823063afe.zip
Merge remote branch 'gnuradio/next'
* gnuradio/next: (806 commits) gruel: added missing ignores gruel: fixed swig interface file to dereference pmt_t. qtgui: fix distcheck error gruel: fixing structure. Passes make check. gruel: SWIGing Gruel into Python to access PMTs. gnuradio-examples: add C++ audio examples using new gr-audio created gruel/attributes.h to house compiler specific attribute macros audio: remove obsoleted individual top-level components gr-audio: added README and default config fix volk: simplify the get new method for the aligned pool grc: moved all usrp1 and usrp2 stuff out of grc and into gr-usrp*/grc grc: swap store the subprocess object rather than the pid when executing qtgui: removed python directory that was added, never used uhd: use %ignore to hide warnings and fix errors Added/updated ignore files. Fixing gr_filter_design program to import from gnuradio Python package. audio: high prio for platform specific audio osx audio: added windows and osx audio source files audio: added config checks for other audios, added jack and port audio: make prefs look like old audio, removed old audio.py ...
Diffstat (limited to 'gnuradio-core/src/guile/dynl-global.c')
-rw-r--r--gnuradio-core/src/guile/dynl-global.c123
1 files changed, 123 insertions, 0 deletions
diff --git a/gnuradio-core/src/guile/dynl-global.c b/gnuradio-core/src/guile/dynl-global.c
new file mode 100644
index 000000000..3bf2741b1
--- /dev/null
+++ b/gnuradio-core/src/guile/dynl-global.c
@@ -0,0 +1,123 @@
+/* -*- 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 <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * 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 <config.h>
+#endif
+
+#include <ltdl.h>
+#include <libguile.h>
+
+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)
+{
+ 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;
+}
+
+#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)
+{
+ 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);
+}