0

I'm wondering how I can get the directory of my program on Linux. For instance, if I have my program located under /home/myproject/ and I get the directory, it should be /home/myproject/ regardless of what directory I'm calling the program from. I need this functionality because I need to be able to access a configuration file located under the same folder as my program, regardless of where the program's folder is located.

I've tried using getcwd(), but here's what it does:

If I'm currently in the same folder as the program is, it will work. However, if I was in /root and tried executing the program which is located under /home/myproject, it would give me /root.

If I just do something like...

std::ifstream is("anotherfile");

It will work as long as I'm in the same directory, but it does the same as above when I'm not.

webminal.org
  • 44,948
  • 37
  • 94
  • 125
  • 3
    `readlink("/proc/self/exe")` - or use some library such as Qt which provides `QCoreApplication::applicationDirPath()` . – Daniel Schepler Feb 01 '18 at 20:08
  • 3
    The UNIX way is to store the configuration file(s) in a known directory, independent of where the executable is located. Typically, the executable is installed somewhere by a root user, and is used by one or more normal users. These users may have their private configuration file, typically named .appname.conf and stored in a user's home directory. A default configuration file is often found in the /etc directory. – Bjorn A. Feb 01 '18 at 20:12
  • 1
    Although I would agree with @BjornA. in general, there are use cases for getting the executable's directory. One I've used is to provide an option to debug an executable from the build directory by placing a path config file in the same directory within the build tree, while not requiring a recompile to then install the executable and have the installed executable get resources from `/usr/share/` or `/usr/local/share/`. – Daniel Schepler Feb 01 '18 at 20:17
  • @BjornA. Thanks, I'm aware that configuration files get stored in /etc/ but I never thought of putting the file there! I'll be using this solution. –  Feb 01 '18 at 21:28

1 Answers1

3

On Linux, you could use /proc/. Read carefully proc(5).

I'm suggesting reading the symlink in /proc/self/exe using readlink(2). It gives your executable. You might use dirname(3) on it to get its directory. Be also aware of realpath(3) which might be useful (actually not, since, as commented by Daniel Schepler, /proc/self/exe is a canonical path....).

This is Linux specific, and won't work in rare pathological cases (your executable being removed or renamed during execution). See this.

Remember that Linux don't have folders (they are just a GUI artefact) but directories. See also opendir(3), readdir(3), closedir(3), stat(2), nftw(3), etc....

At last, the Unix tradition is to keep user-specific configuration files under $HOME (often with hidden dotfile, e.g. $HOME/.inputrc) and system-wide configuration files under /etc/. You can get $HOME with getenv(3) as getenv("HOME"). See environ(7). In pathological cases such a getenv could fail.

BTW, you could even adopt a convention of testing with getenv if some particular environment variable is set (e.g. MYPROGCONFIG) and if it is set, use that as your configuration file. Don't forget to document such conventions.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • I thought `/proc/` and `/proc/self` symlinks already pointed to canonicalized pathnames, due to the kernel implementation being to look up the inode in a reverse name map, or something along those lines. – Daniel Schepler Feb 01 '18 at 20:20