Where am I? Locating yourself on different platforms
It happens every so often that a program needs to figure out where its executable file is located. A common situation is when you are writing a unit test, and your test data is located in the same directory as your binary.
Unfortunately, POSIX does not provide any interface to do that, so if you are writing portable C/C++ code, you are in for an adventure. Below are short code snippets which do that on various platforms. Try to guess which ones work with which platform.
Disclaimer: those are the snippets which I have collected from various API references, StackOverflow answers and SDL source code. I have not tested them, and you should not assume they actually always work correctly.
Variant 1
GetModuleFileName(NULL, path, sizeof(path));
Variant 2
path = getexecname();
Variant 3
/* This is, of course, an oversimplification. In practice, you would want to
* do the link expansion recursively, or at least one level more deep than
* this. */
readlink("/proc/self/exe", path, sizeof(path))
Variant 4(a)
readlink("/proc/curproc/file", path, sizeof(path))
Variant 4(b), from the same platform as above
const int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
sysctl(mib, sizeof(mib), path, sizeof(path), NULL, 0);
Variant 5
_NSGetExecutablePath(path, &path_size);
As a bonus, here is the same problem solved in higher-level languages.
Variant 6 (used in multiple languages)
__FILE__
Variant 7 (strictly speaking, returns the directory instead of the file)
AppDomain.CurrentDomain.BaseDirectory
Variant 8
SomeClass.class.getProtectionDomain().getCodeSource().getLocation().getPath();
The answers here are (highlight to show): #1 is Windows, #2 is Solaris, #3 is Linux, #4 is FreeBSD, #5 is OS X, #6 could be Python, Perl, PHP, Ruby (and probably others as well), #7 is C# and #8 is Java.
In practice, many frameworks (like SDL or Qt) have already solved that
problem once, and you can just call SDL_GetBasePath
or
QCoreApplication::applicationFilePath()
to get the path you
need.