dladdr() in GNU libc isn't available (<dlfcn.h> doesn't define Dl_info)
unless _GNU_SOURCE is defined.

In addition, it's not guaranteed to return anything more useful than
argv[0]; just in case that changes at some point in the future, however,
we still use it, we just run it through the same machinery that we run
argv[0] through.  (On Mac OS X, for example, the path of the executable
is handed to the run-time linker by the kernel, so it *is* useful
there.)

svn path=/trunk/; revision=27821
This commit is contained in:
Guy Harris 2009-03-22 18:06:06 +00:00
parent 4993cb95cd
commit 2f6fe511f3
2 changed files with 38 additions and 32 deletions

View File

@ -677,15 +677,19 @@ else
fi
#
# Check whether we can use dladdr to find the pathname of an executable.
# If we have <dlfcn.h>, check whether we can use dladdr to find a
# filename (hopefully, a full pathname, but no guarantees) for
# the executable.
#
AC_MSG_CHECKING(whether dladdr can be used to find the pathname of an executable)
ac_save_CFLAGS="$CFLAGS"
ac_save_LIBS="$LIBS"
CFLAGS="$CFLAGS $GLIB_CFLAGS"
LIBS="$GLIB_LIBS $LIBS"
AC_TRY_RUN([
#include <stdio.h>
if test "$ac_cv_header_dlfcn_h" = "yes"
then
AC_MSG_CHECKING(whether dladdr can be used to find the pathname of an executable)
ac_save_CFLAGS="$CFLAGS"
ac_save_LIBS="$LIBS"
CFLAGS="$CFLAGS $GLIB_CFLAGS"
LIBS="$GLIB_LIBS $LIBS"
AC_TRY_RUN([
#define _GNU_SOURCE /* required on Linux, sigh */
#include <dlfcn.h>
int
@ -693,23 +697,21 @@ main(void)
{
Dl_info info;
if (!dladdr((const void *)main, &info))
if (!dladdr((void *)main, &info))
return 1; /* failure */
if (info.dli_fname[0] != '/')
return 1; /* not an absolute path - failure */
return 0; /* assume success */
}
], ac_cv_dladdr_finds_executable_path=yes, ac_cv_dladdr_finds_executable_path=no,
[echo $ac_n "cross compiling; assumed OK... $ac_c"
ac_cv_dladdr_finds_executable_path=yes])
CFLAGS="$ac_save_CFLAGS"
LIBS="$ac_save_LIBS"
if test x$ac_cv_dladdr_finds_executable_path = xyes
then
AC_DEFINE(DLADDR_FINDS_EXECUTABLE_PATH, 1, [Define if dladdr can be used to find the path of the executable])
CFLAGS="$ac_save_CFLAGS"
LIBS="$ac_save_LIBS"
if test x$ac_cv_dladdr_finds_executable_path = xyes
then
AC_DEFINE(DLADDR_FINDS_EXECUTABLE_PATH, 1, [Define if dladdr can be used to find the path of the executable])
fi
AC_MSG_RESULT($ac_cv_dladdr_finds_executable_path)
fi
AC_MSG_RESULT($ac_cv_dladdr_finds_executable_path)
dnl IGE Mac integration check
AC_MSG_CHECKING(whether to use IGE Mac integration functions)

View File

@ -26,6 +26,13 @@
# include "config.h"
#endif
/*
* Required with GNU libc to get dladdr().
* We define it here because <dlfcn.h> apparently gets included by
* one of the headers we include below.
*/
#define _GNU_SOURCE
#ifdef HAVE_DIRENT_H
#include <dirent.h>
#endif
@ -368,23 +375,21 @@ init_progfile_dir(const char *arg0
#ifdef DLADDR_FINDS_EXECUTABLE_PATH
/*
* Try to use dladdr() to find the pathname of the executable.
* dladdr() is not guaranteed to give you anything better than
* argv[0] (i.e., it might not contain a / at all, much less
* being an absolute path), and doesn't appear to do so on
* Linux, but on other platforms it could give you an absolute
* path and obviate the need for us to determine the absolute
* path.
*/
if (dladdr((void *)main_addr, &info) && info.dli_fname[0] == '/') {
/*
* dladdr() succeeded, and we got an absolute path
* for the module containing main() (I don't know
* whether it's guaranteed to return an absolute path
* on all platforms), so we'll use that as the
* executable image's path.
*/
prog_pathname = g_strdup(info.dli_fname);
} else
if (dladdr((void *)main_addr, &info))
arg0 = info.dli_fname;
#endif
{
/*
* Try to figure out the directory in which the currently running
* program resides, given the argv[0] it was started with. That
* might be the absolute path of the program, or a path relative
* program resides, given something purporting to be the executable
* name (from dladdr() or from the argv[0] it was started with.
* That might be the absolute path of the program, or a path relative
* to the current directory of the process that started it, or
* just a name for the program if it was started from the command
* line and was searched for in $PATH. It's not guaranteed to be
@ -482,7 +487,6 @@ init_progfile_dir(const char *arg0
return g_strdup("PATH isn't set");
}
}
}
/*
* OK, we have what we think is the pathname