Получить полный путь к исполняемому файлу запущенного процесса в HPUX - PullRequest
1 голос
/ 14 октября 2008

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

Ответы [ 5 ]

9 голосов
/ 09 ноября 2008

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

4 голосов
/ 23 января 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;
}
1 голос
/ 14 октября 2008

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

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

1 голос
/ 17 октября 2008

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

0 голосов
/ 14 октября 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;
}

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

...