Как найти полный путь к программе С++ Linux изнутри?

У меня есть это требование, когда мне нужно найти полный путь для программы на С++ изнутри. Для Windows у меня есть следующее решение. Argv [0] может содержать или не содержать полный путь. Но я должен быть уверен.

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

Что такое эквивалент Linux (gcc) для вышеуказанного кода? Хотелось бы увидеть портативный код.

Ответ 1

В Linux (Posix?) у вас есть символическая ссылка /proc/self/exe, которая ссылается на полный путь исполняемого файла.

В Windows используйте GetModuleFileName.

Никогда не полагайтесь на argv[0], что не гарантируется ничем полезным.

Обратите внимание, что пути и файловые системы не являются частью языка и, следовательно, обязательно зависят от платформы.

Ответ 3

string get_path( )
{
        char arg1[20];
        char exepath[PATH_MAX + 1] = {0};

        sprintf( arg1, "/proc/%d/exe", getpid() );
        readlink( arg1, exepath, 1024 );
        return string( exepath );
}

Ответ 4

Для Linux:
Функция для выполнения системной команды

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;
    }

Затем мы получим имя приложения

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;
}

Затем мы извлекаем путь приложения

    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;
    }

Не забывайте обрезать линию после

Ответ 5

#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);
}

Ответ 6

Если вы пришли сюда, когда Googling для GetModuleFileName Linux... вы, вероятно, ищете возможность сделать это для динамически загружаемых библиотек. Вот как вы это делаете:

struct link_map *lm;
dlinfo(module, RTLD_DI_LINKMAP, &lm);
lm->l_name  // use this