--- glib-2.6.2/glib/gutils.c.orig Mon Jan 3 20:57:20 2005 +++ glib-2.6.2/glib/gutils.c Mon Feb 28 02:13:00 2005 @@ -47,6 +47,12 @@ #include #endif +#ifdef __sun__ +#define _STRUCTURED_PROC 1 +#include +#include +#endif /* __sun__ aka Solaris */ + /* implement gutils's inline functions */ #define G_IMPLEMENT_INLINES 1 @@ -225,6 +231,91 @@ ++p; return p; +} + +/** + * g_get_origin: + + * Get the ORIGIN aka path to this running program. + * + * E.g. if started via /opt/apps/bin/myapp it would return + * /opt/apps/bin. + * + * Return value: a newly-allocated string that must be freed with g_free() or + * %NULL if unable to determine. + */ +gchar * +g_get_origin() +{ +#if defined(__linux__) || defined(__sun__) + char my_origin[MAXPATHLEN] = { '\0' }; + int olen = 0; +#ifdef __sun__ + /* get the name from initial argv[0] */ + psinfo_t ps; + int fd; + char **argv; + + if ( (fd = open("/proc/self/psinfo", O_RDONLY)) > -1 ) { + const char *execname; + int res = read( fd, &ps, sizeof(psinfo_t) ); + if (res > 0) { + argv = (char **) ps.pr_argv; + /* always try argv[0] first */ + if (realpath(argv[0], my_origin) && (my_origin[0] == '/')) { + olen = strlen(my_origin); + } else if ((execname = getexecname())){ + /* no absolute name - so probably invoked like + "eval 'exec perl -S $0 ${1+"$@"}'" or + "#!/bin/env perl" + */ + realpath(execname, my_origin); + olen = strlen(my_origin); + } + } + close(fd); + } +#else /* assume this is __linux__ */ + olen = readlink("/proc/self/exe", my_origin, sizeof(my_origin)); + if ( olen < 1 || my_origin[0] == '[') { + olen = 0; + } +#endif /* __linux__ */ + if (olen > 0) { + /* remove everything after the last / incl. the / itself */ + g_assert(my_origin[0] == '/'); + while (olen > 1 && my_origin[olen - 1] != '/') + --olen; + my_origin[olen - 1] = '\0'; + return g_strdup(my_origin); + } +/* end __linux__ || __sun__ */ +#elif defined(G_OS_WIN32) + /* see glib/gutils:inner_find_program_in_path(...) */ + gchar *path; + if (G_WIN32_HAVE_WIDECHAR_API ()) { + int n; + wchar_t wfilename[MAXPATHLEN]; + n = GetModuleFileNameW (NULL, wfilename, MAXPATHLEN); + if (n > 0 && n < MAXPATHLEN) { + path = g_utf16_to_utf8 (wfilename, -1, NULL, NULL, NULL); + } + } else { + int n; + gchar cpfilename[MAXPATHLEN]; + n = GetModuleFileNameA (NULL, cpfilename, MAXPATHLEN); + if (n > 0 && n < MAXPATHLEN) { + path = g_locale_to_utf8 (cpfilename, -1, NULL, NULL, NULL); + } + } + if (path != NULL) { + gchar *dirname; + dirname = g_path_get_dirname(path); + g_free(path); + return dirname; + } +#endif /* G_OS_WIN32 */ + return NULL; } #ifdef G_OS_WIN32