This will be extremely platform dependent, but for linux, the symlink "/proc/self/exe" points to the physical path of the current image. From here, you can use readlink to determine the path. I recently used this:
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string>
#include <stdexcept>
#include <boost/scoped_array.hpp>
std::string path;
size_t size = 1024;
const ssize_t err = static_cast<ssize_t>(-1);
while (true)
{
boost::scoped_array<char> buffer(new char[size]);
ssize_t res = readlink("/proc/self/exe", buffer.get(), size);
if (res == err)
{
if (errno == ENAMETOOLONG)
size *= 2; // try again
else
throw std::runtime_error("unexpected error during readlink");
}
else
{
path.assign(buffer.get(), res);
break;
}
}
This was done using G++ 4.1.2, so no unique_ptr
available, one could also easily remove the reference to boost::scoped_array
.
Note: this gives you the full path to the current image, not the directory in which the image exists. To get the directory, you'll need to do some manipulation. Boost Filesystem also has some good functionality to do this. Otherwise, you'll have to figure out to parse it yourself.
Also, the above method is great if you're, for instance, a library, and cannot depend upon another portion of code changing the current working directory, or don't have access to argv
. getcwd
+ argv[0]
would work fine if and only if you can guarantee nothing in your application or libraries changes the current working directory (CWD) out from underneath of you. argv[0]
works only if the CWD is unchanged.
Additionally, if the executable is located via an environment variable lookup a la $PATH
, you'd need to implement path resolution to find where you really are. argv[0]
merely returns how you were launched. i.e. if you ran the command "ls -al", argv[0]
to the command "ls" would just be "ls". If you ran "/usr/bin/ls -al", argv[0]
would be "/usr/bin/ls".