From ad4407127e9ba9e46ff7eaa0f61c3a12ac24e704 Mon Sep 17 00:00:00 2001 From: guy Date: Sun, 22 Mar 2009 00:42:33 +0000 Subject: [PATCH] Attempt to use dladdr() to get the pathname of the executable image if it's available and works. git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@27812 f5534014-38df-0310-8fa8-9805f1628bb7 --- capinfos.c | 3 ++- configure.in | 35 +++++++++++++++++++++++++++++++++++ dftest.c | 3 ++- editcap.c | 3 ++- epan/filesystem.c | 31 +++++++++++++++++++++++++++++-- epan/filesystem.h | 2 +- gtk/main.c | 3 ++- rawshark.c | 5 +++-- tshark.c | 3 ++- 9 files changed, 78 insertions(+), 10 deletions(-) diff --git a/capinfos.c b/capinfos.c index 1eb6b6a7e3..8d09fcdf9e 100644 --- a/capinfos.c +++ b/capinfos.c @@ -302,7 +302,8 @@ main(int argc, char *argv[]) #ifdef HAVE_PLUGINS /* Register wiretap plugins */ - if ((init_progfile_dir_error = init_progfile_dir(argv[0]))) { + if ((init_progfile_dir_error = init_progfile_dir(argv[0], + (const void *)main))) { g_warning("capinfos: init_progfile_dir(): %s", init_progfile_dir_error); g_free(init_progfile_dir_error); } else { diff --git a/configure.in b/configure.in index 75ad236a73..d110126399 100644 --- a/configure.in +++ b/configure.in @@ -676,6 +676,41 @@ else have_plugins=no fi +# +# Check whether we can use dladdr to find the pathname of an 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 +#include + +int +main(void) +{ + Dl_info info; + + if (!dladdr((const 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]) +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) diff --git a/dftest.c b/dftest.c index 84b198cbde..7fbadd8bc7 100644 --- a/dftest.c +++ b/dftest.c @@ -75,7 +75,8 @@ main(int argc, char **argv) /* * Attempt to get the pathname of the executable file. */ - init_progfile_dir_error = init_progfile_dir(argv[0]); + init_progfile_dir_error = init_progfile_dir(argv[0], + (const void *)main); if (init_progfile_dir_error != NULL) { fprintf(stderr, "dftest: Can't get pathname of dftest program: %s.\n", init_progfile_dir_error); diff --git a/editcap.c b/editcap.c index 8c541e1b9c..9f2fb28d57 100644 --- a/editcap.c +++ b/editcap.c @@ -424,7 +424,8 @@ main(int argc, char *argv[]) #ifdef HAVE_PLUGINS /* Register wiretap plugins */ - if ((init_progfile_dir_error = init_progfile_dir(argv[0]))) { + if ((init_progfile_dir_error = init_progfile_dir(argv[0], + (const void *)main))) { g_warning("capinfos: init_progfile_dir(): %s", init_progfile_dir_error); g_free(init_progfile_dir_error); } else { diff --git a/epan/filesystem.c b/epan/filesystem.c index 5b522d6b76..79312d3a05 100644 --- a/epan/filesystem.c +++ b/epan/filesystem.c @@ -55,9 +55,12 @@ #include #include #include -#else +#else /* _WIN32 */ +#ifdef DLADDR_FINDS_EXECUTABLE_PATH +#include +#endif /* DLADDR_FINDS_EXECUTABLE_PATH */ #include -#endif +#endif /* _WIN32 */ #include "filesystem.h" #include "report_err.h" @@ -246,6 +249,10 @@ init_progfile_dir(const char *arg0 #ifdef _WIN32 _U_ #endif +, const void *main_addr +#if defined(_WIN32) || !defined(DLADDR_FINDS_EXECUTABLE_PATH) + _U_ +#endif ) { char *dir_end; @@ -334,6 +341,9 @@ init_progfile_dir(const char *arg0 msg, error); } #else +#ifdef DLADDR_FINDS_EXECUTABLE_PATH + Dl_info info; +#endif char *prog_pathname; char *curdir; long path_max; @@ -355,6 +365,22 @@ init_progfile_dir(const char *arg0 && !started_with_special_privs()) running_in_build_directory_flag = TRUE; +#ifdef DLADDR_FINDS_EXECUTABLE_PATH + /* + * Try to use dladdr() to find the pathname of the executable. + */ + if (dladdr(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 +#endif + { /* * Try to figure out the directory in which the currently running * program resides, given the argv[0] it was started with. That @@ -456,6 +482,7 @@ init_progfile_dir(const char *arg0 return g_strdup("PATH isn't set"); } } + } /* * OK, we have what we think is the pathname diff --git a/epan/filesystem.h b/epan/filesystem.h index a97f8d7880..01c2a60d3e 100644 --- a/epan/filesystem.h +++ b/epan/filesystem.h @@ -36,7 +36,7 @@ * and save it for future use. Returns NULL on success, and a * g_mallocated string containing an error on failure. */ -extern char *init_progfile_dir(const char *arg0); +extern char *init_progfile_dir(const char *arg0, const void *main_addr); /* * Get the directory in which the program resides. diff --git a/gtk/main.c b/gtk/main.c index 7ac984b17a..14a96ac837 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -1808,7 +1808,8 @@ main(int argc, char *argv[]) /* * Attempt to get the pathname of the executable file. */ - init_progfile_dir_error = init_progfile_dir(argv[0]); + init_progfile_dir_error = init_progfile_dir(argv[0], + (const void *)main); /* initialize the funnel mini-api */ initialize_funnel_ops(); diff --git a/rawshark.c b/rawshark.c index 9dc10bcb7b..5b3d07af23 100644 --- a/rawshark.c +++ b/rawshark.c @@ -31,7 +31,7 @@ * - Opens a specified file or named pipe * - Applies a specfied DLT or "decode as" encapsulation * - Reads frames prepended with a libpcap packet header. - * - Prints a status line, followed by fields from a specified list. + * - Prints a status line, followed by fields from a specified list. */ #ifdef HAVE_CONFIG_H @@ -460,7 +460,8 @@ main(int argc, char *argv[]) /* * Attempt to get the pathname of the executable file. */ - init_progfile_dir_error = init_progfile_dir(argv[0]); + init_progfile_dir_error = init_progfile_dir(argv[0], + (const void *)main); if (init_progfile_dir_error != NULL) { fprintf(stderr, "rawshark: Can't get pathname of rawshark program: %s.\n", init_progfile_dir_error); diff --git a/tshark.c b/tshark.c index 9ce3f57582..688b0a9836 100644 --- a/tshark.c +++ b/tshark.c @@ -773,7 +773,8 @@ main(int argc, char *argv[]) /* * Attempt to get the pathname of the executable file. */ - init_progfile_dir_error = init_progfile_dir(argv[0]); + init_progfile_dir_error = init_progfile_dir(argv[0], + (const void *)main); if (init_progfile_dir_error != NULL) { fprintf(stderr, "tshark: Can't get pathname of tshark program: %s.\n", init_progfile_dir_error); -- 2.34.1