https://log.vasilvv.org/ Victor's Weblog 2015-01-08T14:17:18Z Victor Vasiliev https://log.vasilvv.org/post/where-am-i Where am I? Locating yourself on different platforms 2015-01-08T14:17:18Z <p>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.</p> <p>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.</p> <p><small><b>Disclaimer:</b> 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. </small></p> <p><b>Variant 1</b> <div class="highlight"><pre><span class="n">GetModuleFileName</span><span class="p">(</span><span class="nb">NULL</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">path</span><span class="p">));</span> </pre></div> <p><b>Variant 2</b></p> <div class="highlight"><pre><span class="n">path</span> <span class="o">=</span> <span class="n">getexecname</span><span class="p">();</span> </pre></div> <p><b>Variant 3</b></p> <div class="highlight"><pre><span class="cm">/* This is, of course, an oversimplification. In practice, you would want to</span> <span class="cm"> * do the link expansion recursively, or at least one level more deep than</span> <span class="cm"> * this. */</span> <span class="n">readlink</span><span class="p">(</span><span class="s">&quot;/proc/self/exe&quot;</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">path</span><span class="p">))</span> </pre></div> <p><b>Variant 4(a)</b></p> <div class="highlight"><pre><span class="n">readlink</span><span class="p">(</span><span class="s">&quot;/proc/curproc/file&quot;</span><span class="p">,</span> <span class="n">path</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">path</span><span class="p">))</span> </pre></div> <p><b>Variant 4(b)</b>, from the same platform as above</p> <div class="highlight"><pre><span class="k">const</span> <span class="kt">int</span> <span class="n">mib</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span> <span class="n">CTL_KERN</span><span class="p">,</span> <span class="n">KERN_PROC</span><span class="p">,</span> <span class="n">KERN_PROC_PATHNAME</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span> <span class="p">};</span> <span class="n">sysctl</span><span class="p">(</span><span class="n">mib</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">mib</span><span class="p">),</span> <span class="n">path</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">path</span><span class="p">),</span> <span class="nb">NULL</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span> </pre></div> <p><b>Variant 5</b></p> <div class="highlight"><pre><span class="n">_NSGetExecutablePath</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">path_size</span><span class="p">);</span> </pre></div> <p>As a bonus, here is the same problem solved in higher-level languages.</p> <p><b>Variant 6</b> <small>(used in multiple languages)</small></p> <div class="highlight"><pre><span class="n">__FILE__</span> </pre></div> <p><b>Variant 7</b> <small>(strictly speaking, returns the directory instead of the file)</small></p> <div class="highlight"><pre><span class="n">AppDomain</span><span class="p">.</span><span class="n">CurrentDomain</span><span class="p">.</span><span class="n">BaseDirectory</span> </pre></div> <p><b>Variant 8</b></p> <div class="highlight"><pre><span class="n">SomeClass</span><span class="p">.</span><span class="n">class</span><span class="p">.</span><span class="n">getProtectionDomain</span><span class="p">().</span><span class="n">getCodeSource</span><span class="p">().</span><span class="n">getLocation</span><span class="p">().</span><span class="n">getPath</span><span class="p">();</span> </pre></div> <p>The answers here are (highlight to show): <span class="spoiler">#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</span>.</p> <p>In practice, many frameworks (like SDL or Qt) have already solved that problem once, and you can just call <code>SDL_GetBasePath</code> or <code>QCoreApplication::applicationFilePath()</code> to get the path you need.</p> https://log.vasilvv.org/post/this-blog-finally-exists Prologue 2014-10-18T19:11:45Z <p>I finally decided to start writing a blog.</p> <p>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.</p> <p>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 <i>real</i> 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.</p> <p>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 href="https://i.imgur.com/Q3cUg29.gif">a somewhat widespread sentiment</a>), so if you find that something is broken for a browser/screen size combination you use, please tell me.</p>