Revision: 2100 http://geany.svn.sourceforge.net/geany/?rev=2100&view=rev Author: eht16 Date: 2007-12-12 12:04:45 -0800 (Wed, 12 Dec 2007)
Log Message: ----------- Add binary relocation support.
Modified Paths: -------------- trunk/ChangeLog trunk/configure.in trunk/src/Makefile.am trunk/src/main.c trunk/src/plugins.c trunk/src/symbols.c
Added Paths: ----------- trunk/src/prefix.c trunk/src/prefix.h
Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2007-12-12 18:42:53 UTC (rev 2099) +++ trunk/ChangeLog 2007-12-12 20:04:45 UTC (rev 2100) @@ -7,6 +7,9 @@ * src/vte.c: Enable dragging of text into the VTE. * src/msgwindow.c: Fix crashes when clicking on message window items introduced with changing rules hints for treeviews. + * configure.in, src/Makefile.am, src/main.c, src/plugins.c, + src/prefix.c, src/prefix.h, src/symbols.c: + Add binary relocation support.
2007-12-09 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
Modified: trunk/configure.in =================================================================== --- trunk/configure.in 2007-12-12 18:42:53 UTC (rev 2099) +++ trunk/configure.in 2007-12-12 20:04:45 UTC (rev 2100) @@ -52,6 +52,61 @@ fi AC_DEFINE_UNQUOTED([REVISION], "$REVISION", [subversion revision number])
+ +dnl Check for binary relocation support +dnl taken from Inkscape (Hongli Lai h.lai@chello.nl) + +AC_ARG_ENABLE(binreloc, + [ --enable-binreloc compile with binary relocation support], + enable_binreloc=$enableval,enable_binreloc=no) + +AC_MSG_CHECKING(whether binary relocation support should be enabled) +if test "$enable_binreloc" = "yes"; then + AC_MSG_RESULT(yes) + AC_MSG_CHECKING(for linker mappings at /proc/self/maps) + if test -e /proc/self/maps; then + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + AC_MSG_ERROR(/proc/self/maps is not available. Binary relocation cannot be enabled.) + enable_binreloc="no" + fi + +elif test "$enable_binreloc" = "auto"; then + AC_MSG_RESULT(yes when available) + AC_MSG_CHECKING(for linker mappings at /proc/self/maps) + if test -e /proc/self/maps; then + AC_MSG_RESULT(yes) + enable_binreloc=yes + + AC_MSG_CHECKING(whether everything is installed to the same prefix) + if test "$bindir" = '${exec_prefix}/bin' -a "$sbindir" = '${exec_prefix}/sbin' -a \ + "$datadir" = '${prefix}/share' -a "$libdir" = '${exec_prefix}/lib' -a \ + "$libexecdir" = '${exec_prefix}/libexec' -a "$sysconfdir" = '${prefix}/etc' + then + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + AC_MSG_NOTICE(Binary relocation support will be disabled.) + enable_binreloc=no + fi + + else + AC_MSG_RESULT(no) + enable_binreloc=no + fi + +elif test "$enable_binreloc" = "no"; then + AC_MSG_RESULT(no) +else + AC_MSG_RESULT(no (unknown value "$enable_binreloc")) + enable_binreloc=no +fi +if test "$enable_binreloc" = "yes"; then + AC_DEFINE(ENABLE_BINRELOC,,[Use AutoPackage?]) +fi + + # GTK checks gtk_modules="gtk+-2.0 >= 2.6.0" PKG_CHECK_MODULES(GTK, [$gtk_modules])
Modified: trunk/src/Makefile.am =================================================================== --- trunk/src/Makefile.am 2007-12-12 18:42:53 UTC (rev 2099) +++ trunk/src/Makefile.am 2007-12-12 20:04:45 UTC (rev 2100) @@ -25,6 +25,7 @@ navqueue.c navqueue.h \ notebook.c notebook.h \ plugins.c plugins.h \ + prefix.c prefix.h \ prefs.c prefs.h \ printing.c printing.h \ project.c project.h \ @@ -75,8 +76,8 @@ geany_LDADD = ../scintilla/libscintilla.a ../tagmanager/libtagmanager.a @GTK_LIBS@ $(INTLLIBS)
INCLUDES = \ - -DPACKAGE_DATA_DIR=""$(datadir)"" -DPACKAGE_LIB_DIR=""$(libdir)"" \ - -DPACKAGE_LOCALE_DIR=""$(prefix)/$(DATADIRNAME)/locale"" \ + -DDATADIR=""$(datadir)"" -DLIBDIR=""$(libdir)"" \ + -DLOCALEDIR=""$(prefix)/$(DATADIRNAME)/locale"" \ -I$(srcdir)/../scintilla/include -I$(srcdir)/../tagmanager/include @GTK_CFLAGS@
clean-local:
Modified: trunk/src/main.c =================================================================== --- trunk/src/main.c 2007-12-12 18:42:53 UTC (rev 2099) +++ trunk/src/main.c 2007-12-12 20:04:45 UTC (rev 2100) @@ -40,6 +40,7 @@ #endif
#include "main.h" +#include "prefix.h" #include "prefs.h" #include "interface.h" #include "support.h" @@ -377,8 +378,8 @@
g_free(install_dir); #else - data_dir = g_strdup(PACKAGE_DATA_DIR "/" PACKAGE "/"); // e.g. /usr/share/geany - doc_dir = g_strdup(PACKAGE_DATA_DIR "/doc/" PACKAGE "/html/"); + data_dir = g_strconcat(DATADIR, "/" PACKAGE "/", NULL); // e.g. /usr/share/geany + doc_dir = g_strconcat(DATADIR, "/doc/" PACKAGE "/html/", NULL); #endif
// convert path names to locale encoding @@ -405,7 +406,7 @@ locale_dir = g_strconcat(install_dir, "\lib\locale", NULL); g_free(install_dir); #else - locale_dir = g_strdup(PACKAGE_LOCALE_DIR); + locale_dir = g_strdup(LOCALEDIR); #endif
bindtextdomain(GETTEXT_PACKAGE, locale_dir);
Modified: trunk/src/plugins.c =================================================================== --- trunk/src/plugins.c 2007-12-12 18:42:53 UTC (rev 2099) +++ trunk/src/plugins.c 2007-12-12 20:04:45 UTC (rev 2100) @@ -33,6 +33,7 @@ #include "Scintilla.h" #include "ScintillaWidget.h"
+#include "prefix.h" #include "plugins.h" #include "plugindata.h" #include "support.h" @@ -534,13 +535,13 @@ path = g_strconcat(app->configdir, G_DIR_SEPARATOR_S, "plugins", NULL); // first load plugins in ~/.geany/plugins/, then in $prefix/lib/geany load_plugins(path); + g_free(path); #ifdef G_OS_WIN32 - g_free(path); path = get_plugin_path(); - load_plugins(path); #else - load_plugins(PACKAGE_LIB_DIR G_DIR_SEPARATOR_S "geany"); + path = g_strconcat(LIBDIR, G_DIR_SEPARATOR_S "geany", NULL); #endif + load_plugins(path);
g_free(path); }
Added: trunk/src/prefix.c =================================================================== --- trunk/src/prefix.c (rev 0) +++ trunk/src/prefix.c 2007-12-12 20:04:45 UTC (rev 2100) @@ -0,0 +1,290 @@ +/* + * BinReloc - a library for creating relocatable executables + * Written by: Mike Hearn mike@theoretic.com + * Hongli Lai h.lai@chello.nl + * http://autopackage.org/ + * + * This source code is public domain. You can relicense this code + * under whatever license you want. + * + * NOTE: if you're using C++ and are getting "undefined reference + * to br_*", try renaming prefix.c to prefix.cpp + */ + + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + + +/* + * enrico - all the code below is only compiled and used if ENABLE_BINRELOC is set in config.h, + * this only happens if configure option --enable-binreloc was used + */ +#ifdef ENABLE_BINRELOC + + + +#include <stdlib.h> +#include <stdio.h> +#include <limits.h> +#include <string.h> +#include <glib.h> +#include "prefix.h" + + +#undef NULL +#define NULL ((void *) 0) + +#ifdef __GNUC__ + #define br_return_val_if_fail(expr,val) if (!(expr)) {fprintf (stderr, "** BinReloc (%s): assertion %s failed\n", __PRETTY_FUNCTION__, #expr); return val;} +#else + #define br_return_val_if_fail(expr,val) if (!(expr)) return val +#endif /* __GNUC__ */ + + +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/param.h> +#include <unistd.h> + + +static char *br_last_value = (char*)NULL; + + +static void +br_free_last_value () +{ + if (br_last_value) + free (br_last_value); +} + +/** + * br_thread_local_store: + * str: A dynamically allocated string. + * Returns: str. This return value must not be freed. + * + * Store str in a thread-local variable and return str. The next + * you run this function, that variable is freed too. + * This function is created so you don't have to worry about freeing + * strings. + * + * Example: + * char *foo; + * foo = thread_local_store (strdup ("hello")); --> foo == "hello" + * foo = thread_local_store (strdup ("world")); --> foo == "world"; "hello" is now freed. + */ +const char * +br_thread_local_store (char *str) +{ + static int initialized = 0; + + + if (!initialized) + { + atexit (br_free_last_value); + initialized = 1; + } + + if (br_last_value) + free (br_last_value); + br_last_value = str; + + return (const char *) str; +} + + +/** + * br_locate: + * symbol: A symbol that belongs to the app/library you want to locate. + * Returns: A newly allocated string containing the full path of the + * app/library that func belongs to, or NULL on error. This + * string should be freed when not when no longer needed. + * + * Finds out to which application or library symbol belongs, then locate + * the full path of that application or library. + * Note that symbol cannot be a pointer to a function. That will not work. + * + * Example: + * --> main.c + * #include "prefix.h" + * #include "libfoo.h" + * + * int main (int argc, char *argv[]) { + * printf ("Full path of this app: %s\n", br_locate (&argc)); + * libfoo_start (); + * return 0; + * } + * + * --> libfoo.c starts here + * #include "prefix.h" + * + * void libfoo_start () { + * --> "" is a symbol that belongs to libfoo (because it's called + * --> from libfoo_start()); that's why this works. + * printf ("libfoo is located in: %s\n", br_locate ("")); + * } + */ +char * +br_locate (void *symbol) +{ + char line[5000]; + FILE *f; + char *path; + + br_return_val_if_fail (symbol != NULL, NULL); + + f = fopen ("/proc/self/maps", "r"); + if (!f) + return NULL; + + while (!feof (f)) + { + unsigned long start, end; + + if (!fgets (line, sizeof (line), f)) + continue; + if (!strstr (line, " r-xp ") || !strchr (line, '/')) + continue; + + sscanf (line, "%lx-%lx ", &start, &end); + if (symbol >= (void *) start && symbol < (void *) end) + { + char *tmp; + size_t len; + + /* Extract the filename; it is always an absolute path */ + path = strchr (line, '/'); + + /* Get rid of the newline */ + tmp = strrchr (path, '\n'); + if (tmp) *tmp = 0; + + /* Get rid of "(deleted)" */ + len = strlen (path); + if (len > 10 && strcmp (path + len - 10, " (deleted)") == 0) + { + tmp = path + len - 10; + *tmp = 0; + } + + fclose(f); + return strdup (path); + } + } + + fclose (f); + return NULL; +} + + +/** + * br_extract_prefix: + * path: The full path of an executable or library. + * Returns: The prefix, or NULL on error. This string should be freed when no longer needed. + * + * Extracts the prefix from path. This function assumes that your executable + * or library is installed in an LSB-compatible directory structure. + * + * Example: + * br_extract_prefix ("/usr/bin/gnome-panel"); --> Returns "/usr" + * br_extract_prefix ("/usr/local/lib/libfoo.so"); --> Returns "/usr/local" + * br_extract_prefix ("/usr/local/libfoo.so"); --> Returns "/usr" + */ +char * +br_extract_prefix (const char *path) +{ + char *end, *tmp, *result; + + br_return_val_if_fail (path != (char*)NULL, (char*)NULL); + + if (!*path) return strdup ("/"); + end = strrchr (path, '/'); + if (!end) return strdup (path); + + tmp = g_strndup ((char *) path, end - path); + if (!*tmp) + { + free (tmp); + return strdup ("/"); + } + end = strrchr (tmp, '/'); + if (!end) return tmp; + + result = g_strndup (tmp, end - tmp); + free (tmp); + + if (!*result) + { + free (result); + result = strdup ("/"); + } + + return result; +} + + +/** + * br_locate_prefix: + * symbol: A symbol that belongs to the app/library you want to locate. + * Returns: A prefix. This string should be freed when no longer needed. + * + * Locates the full path of the app/library that symbol belongs to, and return + * the prefix of that path, or NULL on error. + * Note that symbol cannot be a pointer to a function. That will not work. + * + * Example: + * --> This application is located in /usr/bin/foo + * br_locate_prefix (&argc); --> returns: "/usr" + */ +char * +br_locate_prefix (void *symbol) +{ + char *path, *prefix; + + br_return_val_if_fail (symbol != NULL, NULL); + + path = br_locate (symbol); + if (!path) return NULL; + + prefix = br_extract_prefix (path); + free (path); + return prefix; +} + + +/** + * br_prepend_prefix: + * symbol: A symbol that belongs to the app/library you want to locate. + * path: The path that you want to prepend the prefix to. + * Returns: The new path, or NULL on error. This string should be freed when no + * longer needed. + * + * Gets the prefix of the app/library that symbol belongs to. Prepend that prefix to path. + * Note that symbol cannot be a pointer to a function. That will not work. + * + * Example: + * --> The application is /usr/bin/foo + * br_prepend_prefix (&argc, "/share/foo/data.png"); --> Returns "/usr/share/foo/data.png" + */ +char * +br_prepend_prefix (void *symbol, char *path) +{ + char *tmp, *newpath; + + br_return_val_if_fail (symbol != NULL, NULL); + br_return_val_if_fail (path != NULL, NULL); + + tmp = br_locate_prefix (symbol); + if (!tmp) return NULL; + + if (strcmp (tmp, "/") == 0) + newpath = strdup (path); + else + newpath = g_strconcat (tmp, path, NULL); + + free (tmp); + return newpath; +} + +#endif /* ENABLE_BINRELOC */
Property changes on: trunk/src/prefix.c ___________________________________________________________________ Name: svn:keywords + Author Date Id Revision Name: svn:eol-style + native
Added: trunk/src/prefix.h =================================================================== --- trunk/src/prefix.h (rev 0) +++ trunk/src/prefix.h 2007-12-12 20:04:45 UTC (rev 2100) @@ -0,0 +1,90 @@ +/* + * BinReloc - a library for creating relocatable executables + * Written by: Mike Hearn mike@theoretic.com + * Hongli Lai h.lai@chello.nl + * http://autopackage.org/ + * + * This source code is public domain. You can relicense this code + * under whatever license you want. + * + * See http://autopackage.org/docs/binreloc/ for + * more information and how to use this. + * + * NOTE: if you're using C++ and are getting "undefined reference + * to br_*", try renaming prefix.c to prefix.cpp + */ + +#ifndef _PREFIX_H_ +#define _PREFIX_H_ + + +/* + * enrico - all the code below is only compiled and used if ENABLE_BINRELOC is set in config.h, + * this only happens if configure option --enable-binreloc was used + */ +#ifdef ENABLE_BINRELOC + + +/* WARNING, BEFORE YOU MODIFY PREFIX.C: + * + * If you make changes to any of the functions in prefix.c, you MUST + * change the BR_NAMESPACE macro. + * This way you can avoid symbol table conflicts with other libraries + * that also happen to use BinReloc. + * + * Example: + * #define BR_NAMESPACE(funcName) foobar_ ## funcName + * --> expands br_locate to foobar_br_locate + */ +#undef BR_NAMESPACE +#define BR_NAMESPACE(funcName) geany_ ## funcName + + +#define br_thread_local_store BR_NAMESPACE(br_thread_local_store) +#define br_locate BR_NAMESPACE(br_locate) +#define br_locate_prefix BR_NAMESPACE(br_locate_prefix) +#define br_prepend_prefix BR_NAMESPACE(br_prepend_prefix) + +#ifndef BR_NO_MACROS + /* These are convience macros that replace the ones usually used + in Autoconf/Automake projects */ + #undef SELFPATH + #undef PREFIX + #undef PREFIXDIR + #undef BINDIR + #undef SBINDIR + #undef DATADIR + #undef LIBDIR + #undef LIBEXECDIR + #undef ETCDIR + #undef SYSCONFDIR + #undef CONFDIR + #undef LOCALEDIR + + #define SELFPATH (br_thread_local_store (br_locate ((void *) ""))) + #define PREFIX (br_thread_local_store (br_locate_prefix ((void *) ""))) + #define PREFIXDIR (br_thread_local_store (br_locate_prefix ((void *) ""))) + #define BINDIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/bin"))) + #define SBINDIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/sbin"))) + #define DATADIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/share"))) + #define LIBDIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/lib"))) + #define LIBEXECDIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/libexec"))) + #define ETCDIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/etc"))) + #define SYSCONFDIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/etc"))) + #define CONFDIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/etc"))) + #define LOCALEDIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/share/locale"))) +#endif /* BR_NO_MACROS */ + + +/* The following functions are used internally by BinReloc + and shouldn't be used directly in applications. */ + +const char *br_thread_local_store (char *str); +char *br_locate (void *symbol); +char *br_locate_prefix (void *symbol); +char *br_prepend_prefix (void *symbol, char *path); + + +#endif /* ENABLE_BINRELOC */ + +#endif /* _PREFIX_H_ */
Property changes on: trunk/src/prefix.h ___________________________________________________________________ Name: svn:keywords + Author Date Id Revision Name: svn:eol-style + native
Modified: trunk/src/symbols.c =================================================================== --- trunk/src/symbols.c 2007-12-12 18:42:53 UTC (rev 2099) +++ trunk/src/symbols.c 2007-12-12 20:04:45 UTC (rev 2100) @@ -34,6 +34,7 @@ #include <string.h> #include <stdlib.h>
+#include "prefix.h" #include "symbols.h" #include "utils.h" #include "filetypes.h" @@ -463,12 +464,16 @@
if (icon_theme == NULL) { +#ifndef G_OS_WIN32 + gchar *path = g_strconcat(DATADIR, "/icons", NULL); +#endif gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &x, &y); icon_theme = gtk_icon_theme_get_default(); #ifdef G_OS_WIN32 gtk_icon_theme_append_search_path(icon_theme, "share\icons"); #else - gtk_icon_theme_append_search_path(icon_theme, PACKAGE_DATA_DIR "/icons"); + gtk_icon_theme_append_search_path(icon_theme, path); + g_free(path); #endif }
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.