获取HPUX上正在运行的进程的可执行文件的完整路径
我希望在没有使用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 ... 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:
#include#include #include #include #define _PSTAT64 #include 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”); 返回EXIT_FAILURE; } if(pstat_getpathname(filename,sizeof(filename),&s.pst_fid_text)== -1){ PERROR( “pstat_getpathname”); 返回EXIT_FAILURE; } printf(“filename:%s \ n”,filename); 返回EXIT_SUCCESS; }
关于Unix Programming FAQ的早期答案是正确的。 即使使用Linux / proc答案,问题在于自exec()以来可执行文件的路径可能已更改。 实际上,可执行文件可能已被删除。 考虑链接(符号和硬链接)会产生进一步的复杂性 – 同一个可执行文件可能有多条路径。 没有涵盖所有情况的一般答案,因为可能没有剩余路径,如果有路径,则可能不是唯一的。
也就是说,使用带有某些逻辑的argv [0],正如之前cjhuitt所倡导的,可能会在99.9%的时间内完成你想要的操作。 在进行相对路径检查之前,我会添加一个包含“/”的路径的检查(注意,您必须在任何cwd()调用之前执行此操作)。 请注意,如果你的调用程序感觉很恶作,那么fork()和exec()之间可以做很多事情来搞砸它。 不要依赖于此可能会影响应用程序安全性(如配置文件的位置)。
出于什么目的,您需要可执行路径? 请记住,正如我在之前的post中所说,无法保证可执行文件的路径存在,或者它将是唯一的。
我以前在一般情况下做过这个。 一般的想法是抓住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 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; }
显然,这有一些假设可能会在某些时候破裂,但它应该适用于大多数情况。