From 60260b5701bab73f8de093147de03947c7f264c8 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Mon, 10 Nov 2014 19:29:11 +0200 Subject: [PATCH] Store absolute path to argv[0] in Application Working directory or $PATH may be changed by the program, so it may not be possible to recover the executable later. It's still not completely reliable since the parent process can pass any value for argv[0] through execve(). --- source/core/application.cpp | 13 ++++++++++++- source/fs/dir.cpp | 19 +++++++++++++++++++ source/fs/dir.h | 7 +++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/source/core/application.cpp b/source/core/application.cpp index 0ef9507..1bae2cd 100644 --- a/source/core/application.cpp +++ b/source/core/application.cpp @@ -1,7 +1,10 @@ +#include #include #include #include #include +#include +#include #include #include #include "application.h" @@ -85,7 +88,15 @@ void Application::set_startup_info(const char *argv0, void *data) if(argv0_) throw logic_error("startup info already set"); - argv0_ = argv0; + static FS::Path exe; + + bool has_slash = strchr(argv0, FS::DIRSEP); + if(!has_slash) + exe = FS::path_lookup(argv0); + if(exe.empty()) + exe = FS::realpath(argv0); + + argv0_ = exe.c_str(); data_ = data; } diff --git a/source/fs/dir.cpp b/source/fs/dir.cpp index ffe5670..00385e0 100644 --- a/source/fs/dir.cpp +++ b/source/fs/dir.cpp @@ -220,5 +220,24 @@ void chdir(const Path &path) throw system_error("chdir"); } +Path path_lookup(const string &name, const list &paths) +{ + for(list::const_iterator i=paths.begin(); i!=paths.end(); ++i) + { + Path full = *i/name; + if(exists(full)) + return realpath(full); + } + + return Path(); +} + +Path path_lookup(const string &name) +{ + const char *path = getenv("PATH"); + vector dirs = split(path, ITEMSEP); + return path_lookup(name, list(dirs.begin(), dirs.end())); +} + } // namespace FS } // namespace Msp diff --git a/source/fs/dir.h b/source/fs/dir.h index 6bd760c..d62df8c 100644 --- a/source/fs/dir.h +++ b/source/fs/dir.h @@ -63,6 +63,13 @@ Path get_sys_lib_dir(); /// Changes the current working directory void chdir(const Path &); +/** Looks for a file in a list of paths. Returns the absolute path to the +first existing location, or an empty Path if the file is not found at all. */ +Path path_lookup(const std::string &, const std::list &); + +/** Looks for a file using the PATH environment variable. */ +Path path_lookup(const std::string &); + } // namespace FS } // namespace Msp -- 2.43.0