mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
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.
This commit is contained in:
parent
c12ae077f7
commit
b1ffe2246a
@ -45,6 +45,8 @@
|
||||
#include <unistd.h>
|
||||
#ifdef MAC_INTEGRATION
|
||||
#include <gtkmacintegration/gtkosxapplication.h>
|
||||
#elif GNC_PLATFORM_OSX
|
||||
#include <mach-o/dyld.h>
|
||||
#endif
|
||||
#endif /* ENABLE_BINRELOC */
|
||||
#include <stdio.h>
|
||||
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user