获取HPUX上正在运行的进程的可执行文件的完整路径

Get full path of executable of running process on HPUX

本文关键字:进程 可执行文件 路径 运行 HPUX 获取      更新时间:2023-10-16

我想使用C++代码在没有root权限的情况下获得正在运行的进程(可执行文件)的完整路径。有人能提出实现这一目标的方法吗。

在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为我们提供了可执行文件的完整路径。

类似地,对于windows,我们使用

GetModuleFileName(NULL, exepath, sizeof(exepath));  /* get fullpath of the service */

请帮助我如何在HP-UX上执行此操作,因为HP-UX中没有/proc目录。

首先,我想评论一下您的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),则可能会失败。

在HP-UX上,使用pstat:

#包括<stdio.h>#包括<stdlib.h>#包括<极限.h>#包括<unistd.h>#定义_PSTAT64#包括<sys/pstat.h>int main(int argc,char*argv[]){char文件名[PATH_MAX];结构体pstrongtatus s;if(pstat_getproc(&s,sizeof(s),0,getpid())==-1){perror("pstat_getproc");返回EXIT_FAILURE;}if(pstat_getpathname(文件名,sizeof(文件名),&s.pst_fid_text)==-1){perror("pstat_getpathname");返回EXIT_FAILURE;}printf("filename:%s\n",文件名);return EXIT_SUCCESS;}

前面提到Unix编程常见问题的答案是正确的。即使是Linux/proc的答案,问题也在于可执行文件的路径可能在exec()之后发生了更改。事实上,可执行文件可能已被删除。考虑链接(包括符号和硬链接)会产生更复杂的问题——同一可执行文件可能有多条路径。没有涵盖所有情况的一般答案,因为可能没有剩余的路径,如果有,它可能不是唯一的。

也就是说,使用argv[0]和一些逻辑,正如cjhuitt早些时候所提倡的那样,99.9%的时间可能会做你想要的事情。在进行相对路径检查之前,我会添加一个包含"/"的路径检查(注意,您必须在任何cwd()调用之前进行检查)。请注意,如果您的调用程序感觉很调皮,那么在fork()和exec()之间可以做很多事情来解决这个问题。不要依赖它来处理任何可能影响应用程序安全性的事情(如配置文件的位置)。

您需要可执行路径的目的是什么?请记住,正如我在前面的文章中所说,不能保证可执行文件的路径会存在,也不能保证它是唯一的。

我以前在一般情况下都这样做过。一般的想法是获取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;
}

显然,这有一些假设可能会在某个时候被打破,但它应该适用于大多数情况。

相关文章: