Reputation: 1775
I have this requirement where I need to find the full path for the C++ program from within. For Windows, I have the following solution. The argv[0] may or may not contain the full path. But I need to be certain.
TCHAR drive[_MAX_DRIVE], dir[_MAX_DIR], base[_MAX_FNAME], ext[_MAX_EXT];
TCHAR fullPath[255+1];
_splitpath(argv[0],drive,dir,base,ext);
SearchPath(NULL,base,ext,255,fullPath,NULL);
What is the Linux (gcc) equivalent for the above code? Would love to see a portable code.
Upvotes: 16
Views: 27113
Reputation: 30735
string get_path( )
{
char arg1[20];
char exepath[PATH_MAX + 1] = {0};
sprintf( arg1, "/proc/%d/exe", getpid() );
readlink( arg1, exepath, PATH_MAX );
return string( exepath );
}
Upvotes: 6
Reputation: 2483
The top answer to this question lists techniques for a whole bunch of OSes.
Upvotes: 8
Reputation: 51
#include <string>
#include <unistd.h>
#include <limits.h>
std::string getApplicationDirectory() {
char result[ PATH_MAX ];
ssize_t count = readlink( "/proc/self/exe", result, PATH_MAX );
std::string appPath = std::string( result, (count > 0) ? count : 0 );
std::size_t found = appPath.find_last_of("/\\");
return appPath.substr(0,found);
}
Upvotes: 1
Reputation: 210352
If you came here when Googling for GetModuleFileName Linux
... you're probably looking for the ability to do this for dynamically-loaded libraries. This is how you do it:
struct link_map *lm;
dlinfo(module, RTLD_DI_LINKMAP, &lm);
lm->l_name // use this
Upvotes: 1
Reputation: 1607
For Linux:
Function to execute system command
int syscommand(string aCommand, string & result) {
FILE * f;
if ( !(f = popen( aCommand.c_str(), "r" )) ) {
cout << "Can not open file" << endl;
return NEGATIVE_ANSWER;
}
const int BUFSIZE = 4096;
char buf[ BUFSIZE ];
if (fgets(buf,BUFSIZE,f)!=NULL) {
result = buf;
}
pclose( f );
return POSITIVE_ANSWER;
}
Then we get app name
string getBundleName () {
pid_t procpid = getpid();
stringstream toCom;
toCom << "cat /proc/" << procpid << "/comm";
string fRes="";
syscommand(toCom.str(),fRes);
size_t last_pos = fRes.find_last_not_of(" \n\r\t") + 1;
if (last_pos != string::npos) {
fRes.erase(last_pos);
}
return fRes;
}
Then we extract application path
string getBundlePath () {
pid_t procpid = getpid();
string appName = getBundleName();
stringstream command;
command << "readlink /proc/" << procpid << "/exe | sed \"s/\\(\\/" << appName << "\\)$//\"";
string fRes;
syscommand(command.str(),fRes);
return fRes;
}
Do not forget to trim the line after
Upvotes: 1
Reputation: 476940
On Linux (Posix?) you have a symbolic link /proc/self/exe
which links to the full path of the executable.
On Windows, use GetModuleFileName
.
Never rely on argv[0]
, which is not guaranteed to be anything useful.
Note that paths and file systems are not part of the language and thus necessarily a platform-dependent feature.
Upvotes: 18