From b1ffe2246aa045a966d28bb337af660bd671f731 Mon Sep 17 00:00:00 2001 From: Mike Alexander Date: Mon, 25 May 2020 02:36:59 -0400 Subject: [PATCH] CLean up the binreloc code a bit. It is won't work pervectly, but it's better. Make it do something plausible in a non0QUartz Mac build and make it handle running GnuCash from a symlink. --- libgnucash/core-utils/binreloc.c | 109 ++++++++++--------------------- 1 file changed, 36 insertions(+), 73 deletions(-) diff --git a/libgnucash/core-utils/binreloc.c b/libgnucash/core-utils/binreloc.c index 2e2067e383..f35e55bcf0 100644 --- a/libgnucash/core-utils/binreloc.c +++ b/libgnucash/core-utils/binreloc.c @@ -45,6 +45,8 @@ #include #ifdef MAC_INTEGRATION #include +#elif GNC_PLATFORM_OSX +#include #endif #endif /* ENABLE_BINRELOC */ #include @@ -98,89 +100,46 @@ _br_find_exe (Gnc_GbrInitError *error) } g_free (prefix); return result; -#elif defined MAC_INTEGRATION - gchar *path = gtkosx_application_get_executable_path(); - g_print ("Application Path %s\n", path); - return path; #else - char *path, *path2, *line, *result; - size_t buf_size; - ssize_t size; - struct stat stat_buf; + char path[PATH_MAX + 1], path2[PATH_MAX + 1]; + char *line, *result; + size_t buf_size = PATH_MAX + 1; FILE *f; + uint32_t size2; - /* Read from /proc/self/exe (symlink) */ - if (sizeof (path) > SSIZE_MAX) - buf_size = SSIZE_MAX - 1; - else - buf_size = PATH_MAX - 1; - path = (char *) g_try_malloc (buf_size); - if (path == NULL) +#ifdef MAC_INTEGRATION + result = gtkosx_application_get_executable_path(); + strncpy (path2, result, buf_size - 1); + g_free (result); + g_print ("Application Path %s\n", path2); +#elif defined GNC_PLATFORM_OSX + /* Native Mac, but not Aqua */ + size2 = buf_size; + if (_NSGetExecutablePath (path2, &size2) != 0) { - /* Cannot allocate memory. */ + /* buffer not big enough or some other error */ if (error) *error = GNC_GBR_INIT_ERROR_NOMEM; return NULL; } - path2 = (char *) g_try_malloc (buf_size); - if (path2 == NULL) - { - /* Cannot allocate memory. */ - if (error) - *error = GNC_GBR_INIT_ERROR_NOMEM; - g_free (path); - return NULL; - } - +#else strncpy (path2, "/proc/self/exe", buf_size - 1); +#endif - while (1) + /* Follow all sym links */ + if (realpath (path2, path) != NULL) { - int i; - - size = readlink (path2, path, buf_size - 1); - if (size == -1) - { - /* Error. */ - g_free (path2); - break; - } - - /* readlink() success. */ - path[size] = '\0'; - - /* Check whether the symlink's target is also a symlink. - * We want to get the final target. */ - i = stat (path, &stat_buf); - if (i == -1) - { - /* Error. */ - g_free (path2); - break; - } - - /* stat() success. */ - if (!S_ISLNK (stat_buf.st_mode)) - { - /* path is not a symlink. Done. */ - g_free (path2); - return path; - } - - /* path is a symlink. Continue loop and resolve this. */ - strncpy (path, path2, buf_size - 1); + return g_strdup (path); } - - - /* readlink() or stat() failed; this can happen when the program is + + /* realpath() failed; this can happen when the program is * running in Valgrind 2.2. Read from /proc/self/maps as fallback. */ buf_size = PATH_MAX + 128; - line = (char *) g_try_realloc (path, buf_size); + line = (char *) g_try_malloc (buf_size); if (line == NULL) { /* Cannot allocate memory. */ - g_free (path); if (error) *error = GNC_GBR_INIT_ERROR_NOMEM; return NULL; @@ -221,10 +180,10 @@ _br_find_exe (Gnc_GbrInitError *error) line[buf_size - 1] = 0; /* Extract the filename; it is always an absolute path. */ - path = strchr (line, '/'); + result = strchr (line, '/'); /* Sanity check. */ - if (strstr (line, " r-xp ") == NULL || path == NULL) + if (strstr (line, " r-xp ") == NULL || result == NULL) { fclose (f); g_free (line); @@ -233,10 +192,9 @@ _br_find_exe (Gnc_GbrInitError *error) return NULL; } - path = g_strdup (path); - g_free (line); + result = g_strdup (result); fclose (f); - return path; + return result; #endif /* ENABLE_BINRELOC */ } @@ -410,12 +368,17 @@ get_mac_bundle_prefix() #if defined ENABLE_BINRELOC && defined MAC_INTEGRATION gchar *id = gtkosx_application_get_bundle_id (); gchar *path = gtkosx_application_get_resource_path (); - if (id == NULL) + /* If id is nullthe app is unbundled and the path + is just the path to the application directory. + We already have that and our version is better. + If GNC_UNINSTALLED is set then we're running from + GNC_BUILDDIR. + */ + if (id == NULL || g_getenv ("GNC_UNINSTALLED")) { - gchar *dirname = g_path_get_dirname (path); g_free (path); g_free (id); - return dirname; + return NULL; } g_free (id); return path;