Я хочу получить полный путь к запущенному процессу (исполняемому файлу) без прав root, используя код C++. Может кто-нибудь предложить способ добиться этого.
на платформах Linux я могу сделать это следующим образом.
char exepath[1024] = {0};
char procid[1024] = {0};
char exelink[1024] = {0};
sprintf(procid, "%u", getpid());
strcpy(exelink, "/proc/");
strcat(exelink, procid);
strcat(exelink, "/exe");
readlink(exelink, exepath, sizeof(exepath));
Здесь exepath дает нам полный путь к исполняемому файлу.
Аналогично для окон мы делаем это, используя
GetModuleFileName(NULL, exepath, sizeof(exepath)); /* get fullpath of the service */
Пожалуйста, помогите мне, как это сделать в HP-UX, поскольку в HP-UX нет каталога / proc.





Я делал это раньше в общем случае. Общая идея состоит в том, чтобы взять argv [0] и обработать его:
int main( int argc, char** argv )
{
string full_prog_path = argv[0];
if ( full_prog_path[0] == "/" )
{ // It was specified absolutely; no processing necessary.
}
else
{
string check_cwd = getcwd();
check_cwd += argv[0];
if ( FileExists( check_cwd ) )
{ // It was specified relatively.
full_prog_path = check_cwd;
}
else
{ // Check through the path to find it
string path = getenv( "PATH" );
list<string> paths = path.split( ":" );
foreach( test_path, paths )
{
if ( FileExists( test_path + argv[0] ) )
{ // We found the first path entry with the program
full_prog_path = test_path + argv[0];
break;
}
}
}
}
cout << "Program path: " << full_prog_path << endl;
return 0;
}
Очевидно, что здесь есть некоторые предположения, которые в какой-то момент могут сломаться, но в большинстве случаев это должно работать.
В простых случаях это нормально. Однако это ненадежно. Я мог бы написать: execl ("/ путь / к / вашей / программе", "../../penguins/rule/the/world", "arg1", (char *) 0); а значение argv [0] не похоже на имя исполняемого файла.
@Jonathan: Как я уже сказал, у него есть некоторые предположения, но он работает в большинстве случаев. Я не знаю ни одного способа обработки сценария, который вы упоминаете в коде.
Предыдущий ответ, относящийся к часто задаваемым вопросам программирования для Unix, был правильным. Проблема, даже с ответом Linux / proc, заключается в том, что путь к исполняемому файлу мог измениться с момента exec (). Фактически, исполняемый файл мог быть удален. Дальнейшие сложности возникают при рассмотрении ссылок (как символьных, так и жестких) - к одному и тому же исполняемому файлу может быть несколько путей. Не существует общего ответа, охватывающего все случаи, поскольку путь может не остаться, а если он есть, то он может быть не уникальным.
Тем не менее, использование argv [0] с некоторой логикой, как было рекомендовано cjhuitt ранее, вероятно, будет делать то, что вы хотите, в 99,9% случаев. Я бы добавил проверку пути, содержащего "/", перед выполнением проверки относительного пути (и обратите внимание, вы должны сделать это перед любыми вызовами cwd ()). Обратите внимание: если ваша вызывающая программа кажется непослушной, есть множество вещей, которые можно сделать между fork () и exec (), чтобы все испортить. Не полагайтесь на это ни в чем, что может повлиять на безопасность приложения (например, расположение файлов конфигурации).
Для чего нужен путь к исполняемому файлу? Имейте в виду, как я писал в своем предыдущем посте, что нет гарантии, что путь к исполняемому файлу будет существовать или что он будет уникальным.
Во-первых, я хотел бы прокомментировать ваше решение для Linux: оно примерно в 5 раз длиннее, чем должно быть, и выполняет множество совершенно ненужных операций, а также использует магическое число 1024, что просто неправильно:
$ grep PATH_MAX /usr/include/linux/limits.h
#define PATH_MAX 4096 /* # chars in a path name */
Вот правильная минимальная замена:
#include <limits.h>
...
char exepath[PATH_MAX] = {0};
readlink("/proc/self/exe", exepath, sizeof(exepath));
Во-вторых, в HP-UX вы можете использовать shl_get_r() для получения информации обо всех загруженных модулях. В индексе 0 вы найдете информацию об основном исполняемом файле. desc.filename будет указывать на имя исполняемого файла во время execve(2).
К сожалению, это имя является относительным, поэтому вам, возможно, придется искать $PATH, и он может потерпеть неудачу, если приложение сделало putenv("PATH=some:new:path") или если исходное имя exename было, например, ./a.out, и с тех пор приложение выполняет chdir(2).
Человек, кажется, указывает, что «readlink () не добавляет нулевой байт к buf. Он усекает содержимое (до длины bufsiz символов), если буфер слишком мал, чтобы вместить все содержимое».
В HP-UX используйте pstat:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <unistd.h>
#define _PSTAT64
#include <sys/pstat.h>
int main(int argc, char *argv[])
{
char filename[PATH_MAX];
struct pst_status s;
if (pstat_getproc(&s,sizeof(s),0,getpid()) == -1) {
perror("pstat_getproc");
return EXIT_FAILURE;
}
if (pstat_getpathname(filename,sizeof(filename),&s.pst_fid_text) == -1) {
perror("pstat_getpathname");
return EXIT_FAILURE;
}
printf("filename: %s\n",filename);
return EXIT_SUCCESS;
}
Этот пример от HP сначала объединяет стандартные подходы, а затем возвращается к pstat: h21007.www2.hp.com/portal/site/dspp/…
почему бы вам не создать такую строку ?: snprintf (exelink, sizeof (exelink), "/ proc /% u / exe", getpid ()); Я вижу в вашем коде 3 буфера и 4 строки, посвященные тому, что должно быть 1 буфером и 1 строкой.