getcwd behaves inconsistent?

Nick Sabalausky SeeWebsiteToContactMe at semitwist.com
Mon Jun 18 13:53:58 PDT 2012


"Kapps" <opantm2+spam at gmail.com> wrote in message 
news:jikemjmapclwcufpwnjz at forum.dlang.org...
> On Sunday, 17 June 2012 at 22:39:00 UTC, Stephen Jones wrote:
>> I recently switched from Eclipse to monoD and found that all my code to 
>> images etc was invalid because getcwd returns the directory that contains 
>> the main entry code in Eclipse, but returns the directory that contains 
>> the executable in MonoDevelop. Is there a universally consistent way of 
>> accessing files?
>
> As mentioned, it is not reliable to use the current working directory for 
> making a relative path absolute.
>

Right. "Current Working Directory" and "Directory of Executable" should 
never be confused:

- The working directory should be assumed to always be different, as it's 
whatever directory the user just happens to be in when they run your 
program.

- If you want to load files that are relative to the exe's path, then you 
need the directory of the executble. The working directory won't help at 
all. Note that args[0] is *not* good for this either, as that gets screwed 
up by symlinks and all sorts of other stuff. args[0] is unreliable.

> The approach I use is GetModuleFileNameA on Windows 
> (GetModuleFileNameA(null, Buffer.ptr, MAX_PATH)) and readLinkPosix for 
> /proc/self/exe on Linux (readLinkPosix("/proc/self/exe", Buffer.ptr, 
> Buffer.length)).

Yea, that's definitely the way to go. Here are ready-to-go functions that 
should handle that on Windows, Linux and OSX (untested on OSX as I don't 
have a working Mac, but theoretically *should* work):

https://bitbucket.org/Abscissa/semitwistdtools/src/8123e04b593c/src/semitwist/util/io.d#cl-168

(Ignore the commented out function - that's just a remenant from the 
D1/Tango days, I should probably just delete that.)

Use those functions like this:

// Assuming the exe is "C:\Foo\Bar\App.exe"
assert(getExec() == `C:\Foo\Bar\App.exe`);
assert(getExecName() == `App.exe`);
assert(getExecPath() == `C:\Foo\Bar\`);

You should be able to rip those functions right out of that file and plop 
them into any util module you have, just make sure you also include these 
import lines:

version(Win32)
    import std.c.windows.windows;
else version(OSX)
    private extern(C) int _NSGetExecutablePath(char* buf, uint* bufsize);
else
    import std.c.linux.linux;




More information about the Digitalmars-d mailing list