Victor's Weblog

Hi! I'm Victor Vasiliev. I study math and computer science at MIT, and spend my spare time writing open source software and playing video games. I also used to be active as MediaWiki developer.

GitHub: vasilvv
Twitter: @vasilvv_
Email: vasilvv@mit.edu

Atom feed · Archive

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.

Prologue

I finally decided to start writing a blog.

I've wanted to do that for quite a while; the issue was that I could not find a platform I liked. WordPress seemed like an overkill, many of more minimalist solutions were written in Ruby, which I can't speak... In short, I ended up writing my own blogging engine using Flask.

I am baffled by how well-developed web frameworks for Python are these days. You see, even though I've spent quite a while improving various parts of MediaWiki (which is decidedly a webapp), I've never actually worked with any real web frameworks, even for PHP. MediaWiki was written in vanilla PHP, back when it was an actual improvement over Perl. Over time it grew its very own supporting framework-library; it includes some quite crazy features, like a reverse-engineered IE6 content sniffer and a Lua sandbox. At the same time it is missing some things which you would normally consider vital, like an HTML templating system. So when I discovered that I made a blog in just 300 lines of code, only ~100 of which were Python, I was very confused and tried hard to figure out which important part I am missing.

Most of the time I spent on this was debugging CSS to make sure that website is responsive and works well on some reasonable subset of browsers. I still have a feeling that I actually have no idea how CSS works (that is apparently a somewhat widespread sentiment), so if you find that something is broken for a browser/screen size combination you use, please tell me.