Cleaned up Application::GetExeDirectory

This commit is contained in:
Gunnar Beutner 2012-06-15 22:26:25 +02:00
parent 9ab3f6aaba
commit 10138c7ff8
2 changed files with 31 additions and 43 deletions

View File

@ -338,69 +338,56 @@ void Application::Log(LogSeverity severity, string facility, string message)
*/ */
string Application::GetExeDirectory(void) const string Application::GetExeDirectory(void) const
{ {
static string ExePath; static string result;
if (ExePath.length() != 0) if (!result.empty())
return ExePath; return result;
#ifndef _WIN32 #ifndef _WIN32
char Cwd[MAXPATHLEN]; string argv0 = m_Arguments[0];
char *PathEnv, *Directory, PathTest[MAXPATHLEN], FullExePath[MAXPATHLEN];
bool FoundPath;
const char *argv0 = m_Arguments[0].c_str(); char buffer[MAXPATHLEN];
if (getcwd(buffer, sizeof(buffer)) == NULL)
if (getcwd(Cwd, sizeof(Cwd)) == NULL)
throw PosixException("getcwd failed", errno); throw PosixException("getcwd failed", errno);
string workingDirectory = buffer;
// TODO:: C++ify this.
if (argv0[0] != '/') if (argv0[0] != '/')
snprintf(FullExePath, sizeof(FullExePath), "%s/%s", Cwd, argv0); result = workingDirectory + "/" + argv0;
else else
strncpy(FullExePath, argv0, sizeof(FullExePath)); result = argv0;
if (strchr(argv0, '/') == NULL) { if (argv0.find_first_of('/') == string::npos) {
PathEnv = getenv("PATH"); const char *pathEnv = getenv("PATH");
if (pathEnv != NULL) {
vector<string> paths;
boost::algorithm::split(paths, pathEnv, boost::is_any_of(":"));
if (PathEnv != NULL) { bool foundPath = false;
PathEnv = strdup(PathEnv); for (vector<string>::iterator it = paths.begin(); it != paths.end(); it++) {
string pathTest = *it + "/" + argv0;
if (PathEnv == NULL)
throw runtime_error("strdup failed");
FoundPath = false;
for (Directory = strtok(PathEnv, ":"); Directory != NULL; Directory = strtok(NULL, ":")) {
if (snprintf(PathTest, sizeof(PathTest), "%s/%s", Directory, argv0) < 0)
throw PosixException("snprintf failed", errno);
if (access(PathTest, X_OK) == 0) {
strncpy(FullExePath, PathTest, sizeof(FullExePath));
FoundPath = true;
if (access(pathTest.c_str(), X_OK) == 0) {
result = pathTest;
foundPath = true;
break; break;
} }
} }
free(PathEnv); if (!foundPath) {
result.clear();
if (!FoundPath)
throw runtime_error("Could not determine executable path."); throw runtime_error("Could not determine executable path.");
}
} }
} }
char Buf[PATH_MAX]; if (realpath(result.c_str(), buffer) == NULL)
if (realpath(FullExePath, Buf) == NULL)
throw PosixException("realpath failed", errno); throw PosixException("realpath failed", errno);
// remove filename result = buffer;
char *LastSlash = strrchr(Buf, '/');
if (LastSlash != NULL) size_t pos = result.find_last_of('/');
*LastSlash = '\0'; if (pos != string::npos)
result.erase(pos);
ExePath = string(Buf);
#else /* _WIN32 */ #else /* _WIN32 */
char FullExePath[MAXPATHLEN]; char FullExePath[MAXPATHLEN];
@ -408,10 +395,10 @@ string Application::GetExeDirectory(void) const
PathRemoveFileSpec(FullExePath); PathRemoveFileSpec(FullExePath);
ExePath = string(FullExePath); result = FullExePath;
#endif /* _WIN32 */ #endif /* _WIN32 */
return ExePath; return result;
} }
/** /**

View File

@ -113,6 +113,7 @@ using std::domain_error;
#include <boost/function.hpp> #include <boost/function.hpp>
#include <boost/signal.hpp> #include <boost/signal.hpp>
#include <boost/algorithm/string/trim.hpp> #include <boost/algorithm/string/trim.hpp>
#include <boost/algorithm/string/split.hpp>
using boost::shared_ptr; using boost::shared_ptr;
using boost::weak_ptr; using boost::weak_ptr;