我希望在没有使用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目录。
答案 0 :(得分:9)
首先,我想对你的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)
。
答案 1 :(得分:4)
在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; }
答案 2 :(得分:1)
早期的答案指的是Unix Programming FAQ是对的。即使使用Linux / proc答案,问题在于自exec()以来可执行文件的路径可能已更改。实际上,可执行文件可能已被删除。考虑链接(符号和硬链接)会产生进一步的复杂性 - 同一个可执行文件可能有多条路径。没有涵盖所有情况的一般答案,因为可能没有剩余的路径,如果有路径,它可能不是唯一的。
也就是说,使用argv [0]和一些逻辑,正如之前cjhuitt所倡导的那样,99.9%的时间可能会做你想要的。在进行相对路径检查之前,我会添加一个包含“/”的路径的检查(注意,您必须在任何cwd()调用之前执行此操作)。请注意,如果你的调用程序感觉很恶作,那么fork()和exec()之间可以做很多事情来搞砸它。不要将此依赖于任何可能影响应用程序安全性的内容(例如配置文件的位置)。
答案 3 :(得分:1)
您需要可执行路径的目的是什么?请记住,正如我在前面的帖子中所说,无法保证可执行文件的路径存在,或者它将是唯一的。
答案 4 :(得分:0)
我以前在一般情况下做过这个。一般的想法是抓住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;
}
显然,这有一些假设可能会在某些时候破裂,但它应该适用于大多数情况。