Получить полный путь к исполняемому файлу запущенного процесса на HPUX

Я хочу получить полный путь к запущенному процессу (исполняемому файлу) без разрешения 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.


person user27804    schedule 14.10.2008    source источник
comment
почему бы вам не создать такую ​​строку?: snprintf(exelink, sizeof(exelink), /proc/%u/exe, getpid()); Я вижу в вашем коде 3 буфера и 4 строки, посвященные тому, что должно быть 1 буфером и 1 строкой.   -  person Evan Teran    schedule 14.10.2008


Ответы (5)


Во-первых, я хотел бы прокомментировать ваше решение для 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") или если исходное имя exe было, например, . ./a.out и с тех пор приложение выполнялось chdir(2).

person Community    schedule 09.11.2008
comment
Кажется, человек указывает, что readlink() не добавляет нулевой байт к buf. Он обрезает содержимое (до длины символов bufsiz), если буфер слишком мал для хранения всего содержимого. - person rpg; 09.07.2009

В 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;
}
person Randy Proctor    schedule 23.01.2009
comment
В этом примере от HP сначала сочетаются стандартные подходы, а затем возвращается к pstat: "nofollow noreferrer">h21007.www2.hp.com/portal/site/dspp/ - person pixelbeat; 24.01.2009

Предыдущий ответ, относящийся к часто задаваемым вопросам по программированию Unix, был правильным. Проблема, даже с ответом Linux /proc, заключается в том, что путь к исполняемому файлу мог измениться с момента вызова exec(). На самом деле исполняемый файл мог быть удален. Дальнейшие сложности возникают при рассмотрении ссылок (как символических, так и жестких) — может быть несколько путей к одному и тому же исполняемому файлу. Общего ответа, охватывающего все случаи, не существует, так как пути может и не остаться, а если и есть, то он может быть не единственным.

Тем не менее, использование argv[0] с некоторой логикой, как ранее рекомендовал cjhuitt, вероятно, будет делать то, что вы хотите, в 99,9% случаев. Я бы добавил проверку пути, содержащего «/», перед выполнением проверки относительного пути (и обратите внимание, что вы должны сделать это перед любыми вызовами cwd()). Обратите внимание, что если ваша вызывающая программа ведет себя неадекватно, между fork() и exec() можно сделать множество вещей, чтобы все испортить. Не полагайтесь на это во всем, что может повлиять на безопасность приложения (например, расположение файлов конфигурации).

person mpez0    schedule 14.10.2008

Для какой цели вам нужен исполняемый путь? Имейте в виду, как я писал в своем предыдущем посте, что нет никакой гарантии, что путь к исполняемому файлу будет существовать или что он будет уникальным.

person mpez0    schedule 17.10.2008

Я делал это раньше в общем случае. Общая идея состоит в том, чтобы получить 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;
}

Очевидно, что здесь есть некоторые допущения, которые в какой-то момент могут сломаться, но в большинстве случаев это должно работать.

person Community    schedule 14.10.2008
comment
В простых случаях это нормально. Однако это ненадежно. Я мог бы написать: execl(/path/to/your/program, ../../penguins/rule/the/world, arg1, (char *)0); а значение argv[0] не имеет ничего общего с именем исполняемого файла. - person Jonathan Leffler; 09.11.2008
comment
@Jonathan: Как я уже сказал, у него есть некоторые предположения, но он работает в большинстве случаев. Я не знаю, как справиться со сценарием, который вы упомянули в коде. - person Caleb Huitt - cjhuitt; 13.11.2008