Store absolute path to argv[0] in Application
authorMikko Rasa <tdb@tdb.fi>
Mon, 10 Nov 2014 17:29:11 +0000 (19:29 +0200)
committerMikko Rasa <tdb@tdb.fi>
Mon, 10 Nov 2014 17:29:11 +0000 (19:29 +0200)
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
source/fs/dir.cpp
source/fs/dir.h

index 0ef9507a14275af33fadbd1a73f190528e8f1601..1bae2cd68d06c1028c08e8690dbe585c79b6eb9c 100644 (file)
@@ -1,7 +1,10 @@
+#include <cstring>
 #include <typeinfo>
 #include <signal.h>
 #include <msp/debug/demangle.h>
 #include <msp/debug/errorreporter.h>
+#include <msp/fs/dir.h>
+#include <msp/fs/path.h>
 #include <msp/fs/utils.h>
 #include <msp/io/print.h>
 #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;
 }
 
index ffe56708bffeb85552839e6867663470b9b0a418..00385e0d52d5602251719da1f3dc61859ccaecec 100644 (file)
@@ -220,5 +220,24 @@ void chdir(const Path &path)
                throw system_error("chdir");
 }
 
+Path path_lookup(const string &name, const list<Path> &paths)
+{
+       for(list<Path>::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<string> dirs = split(path, ITEMSEP);
+       return path_lookup(name, list<Path>(dirs.begin(), dirs.end()));
+}
+
 } // namespace FS
 } // namespace Msp
index 6bd760ced68be0ea6bdd57934d2cce925a32e70d..d62df8cde781896d30fc64a1f99091fa22c3fcef 100644 (file)
@@ -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<Path> &);
+
+/** Looks for a file using the PATH environment variable. */
+Path path_lookup(const std::string &);
+
 } // namespace FS
 } // namespace Msp