tags:

views:

691

answers:

4

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.

I'm on Linux using g++, Thanx in advance

A: 

You can get the path of the running program by reading the command line. In linux you can get the command line by reading /proc folder as /proc/PID/CommandLine

Vinay
+2  A: 

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.

I still don't see the reason to know your current dir name.

#include <boost/filesystem/convenience.hpp>

#include <iostream>
#include <ostream>

int main(int argc, char** argv)
{
    boost::filesystem::path argvPath( argv[0] );
    boost::filesystem::path executablePath( argvPath.parent_path() );
    boost::filesystem::path runPath( boost::filesystem::initial_path() );

    std::cout << executablePath << std::endl;
    std::cout << runPath << std::endl;
    return 0;
}
Mykola Golubyev
+7  A: 

EDIT - don't use getcwd(), it's just where the user is not where the executable is.

See here for details.

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).

plinth
"...it's not really UNIX form..." Which form it is? I thought it's not really ANY_OS_FORM.
Mykola Golubyev
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 - dribeas
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.
plinth
A: 

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:

install-dir/bin/program
install-dir/bin/real-program
install-dir/etc/config
install-dir/data/book-file.mobi
Zan Lynx