我正在将一个Linux C03应用程序移植到达尔文OS X上,并且有一些代码可以读取/proc/self/exe中的符号链接,以确定正在运行的可执行文件所在的目录。
如何计算当前运行在Macintosh达尔文OS X Mavericks上的C可执行文件的目录?
下面是我在Linux上运行的代码:
bool
resolveBinaryLocation(string &binaryDirname)
{
// Read the symbolic link '/proc/self/exe'.
const char *linkName = "/proc/self/exe";
const size_t bufSize = PATH_MAX + 1;
char dirNameBuffer[bufSize];
const int ret = int(readlink(linkName, dirNameBuffer, bufSize - 1));
if (ret == -1) {
// Permission denied (We must be inetd with this app run as other than root).
return false;
}
dirNameBuffer[ret] = 0; // Terminate the string with a NULL character.
binaryDirname = dirNameBuffer;
// Erase the name of the executable:
string::size_type last = binaryDirname.size() - 1;
string::size_type idx = binaryDirname.rfind(DSI_PATH_CHAR, last);
// Add one to keep the trailing directory separator.
binaryDirname.erase(idx + 1);
return true;
}
2条答案
按热度按时间daupos2t1#
以下是我的解决方案:
v6ylcynt2#
值得一提的是,
/proc/self/exe
和_NSGetExecutablePath
不等价。如果可执行文件在运行时被删除或替换,则打开/proc/self/exe
仍将打开可执行文件的运行版本,而打开_NSGetExecutablePath
将失败(如果已删除)或改为打开新版本如果重要的是要获得一个与
/proc/self/exe
等效的macOS,即使可执行文件被删除/替换,一个选项是在启动期间打开_NSGetExecutablePath
的FD并保持打开状态。假设FD为3,那么/dev/fd/3
的行为 * 大部分 * 类似于Linux/proc/self/exe
,包括删除/替换可执行文件时的相同行为。(一个区别是你可以在Linux上使用/proc/self/exe
进行自我执行,而macOS没有fexecve
,apparently不会让你在/dev/fd
中执行任何东西。从理论上讲,这里可能存在竞态条件:在启动和打开自身之间,可执行文件可以被新版本替换或删除。人们可能会认为这样的竞争条件非常罕见,因此没有必要担心它;但如果要处理的话,我有两个建议:
_NSGetExecutablePath()
返回的路径失败(可执行文件在启动时被删除,或其他一些奇怪的情况)-只需中止并显示错误消息。LC_UUID
是否与您自己的相同-如果它们不同,则中止并显示错误消息(意味着在启动时出现了新版本的可执行文件)。如果不能选择中止,您可以尝试执行新版本。