Hey, I've been writing a program (a sort of e-Book viewing type thing) and it loads text files from a folder within the folder of which the executable is located. This gives me a bit of a problem since if I run the program from another directory with the command "./folder/folder/program" for example, my program will not find the text, because the working directory isn't correct. I cannot have an absolute directory because I would like the program to be portable. Is there any way to get the precise directory that the executable is running from even if it has been run from a different directory. I've heard could combine argc[0] and getcwd() but argc is truncated when there is a space in the directory, (I think?) so I would like to avoid that if possible.

argc is the argument count; argv is the argument vector (array of pointers to strings). argv[0] is not truncated by spaces; argv[0] is chosen by the program that launches the program and does not necessarily bear any relationship to the path of the program. Don't add getcwd() if argv[0] starts '/'.
–
Jonathan LefflerApr 10 '09 at 15:57

Do you have access to the boost library?
–
Mykola GolubyevApr 10 '09 at 16:03

Wait a second. Do you need a "executable path" or "directory that the executable is running from"?
–
Mykola GolubyevApr 10 '09 at 16:08

4 Answers
4

On linux /proc/<pid>/exe or /proc/self/exe should be a symbolic link to your executable. Like others, I think the more important question is "why do you need this?" It's not really UNIX form to use the executable path to find ancillary files. Instead you use an environment variable or a default location, or follow one of the other conventions for finding the location of ancillary files (ie, ~/.<myapp>rc).

"...it's not really UNIX form..." Which form it is? I thought it's not really ANY_OS_FORM.
–
Mykola GolubyevApr 10 '09 at 16:04

As plinth recommends: add a config file/directory for the user/system and search full paths. As an example, global config files should go in /etc, while user config files usually are in ~/.<program>rc for a file or under a ~/.<program> directory.
–
David Rodríguez - dribeasApr 10 '09 at 16:41

Mykola - it's more 1980's Macintosh/Windows form. My app lives in one folder and its support files lives relative to it. To find support files, one first finds where the app is.
–
plinthApr 10 '09 at 18:33

@plinth: One reason one might need this is, for example, a program which can be installed to either /usr or /usr/local or /opt or $HOME/app or $HOME/.local/ or anywhere else. If you then need to load support files, how do you decide where to look? Worse, what if it's moved? Finding the executable's path allows you to package the app without knowing where it will be put. This is my current use case.
–
greyfadeJun 25 '12 at 3:05

When you add a book to your library you can remember its absolute path.
It is not a bad when your program rely on the fact that it will be launched from the working dir and not from some other dir. That's why there are all kinds of "links" with "working dir" parameter.

You don't have to handle such situations in the way you want. Just check if all necessary files and dirs structure are in place and log an error with the instructions if they are not.

Or every time when your program starts and doesn't find necessary files the program can ask to point the path to the Books Library.

argv[0] is not truncated when there are spaces. However, it will only have the program name and not the path when a program is run from a directory listed in the PATH environment variable.

In any case, what you are trying to do here is not good design for a Unix/Linux program. Data files are not stored in the same directory as program files because doing so makes it difficult to apply proper security policies.

The best way to get what you want in my opinion is to use a shell script to launch the actual program. This is very similar to how Firefox launches on Linux systems. The shell places the name of the script into $0 and this variable will always have a path. Then you can use an environment variable or command line argument to give your program the location of the data files, like this:

dir=`dirname "$0"`
cd "$dir/../data/"
"$dir/real-program"

And I would arrange your program so that it's files are somewhat like this: