Phi*_*hil 3 path executable arguments
argv[0]
引用导致当前进程加载的 shell 命令。getcwd()
返回当前工作目录。根据该信息,我可以构造程序的二进制可执行文件的绝对路径吗?如果程序cd
自首次加载以来已经完成了 a,我不希望它起作用。
在编程语言解释器的内部,我使用以下代码来获取自身路径。
它有针对 Linux、Windows(包括 Cygwin)、Mac 和 Solaris 的特殊代码:
#if __APPLE__
#include <mach-o/dyld.h>
#endif
#if __linux__
static val get_self_path(void)
{
char self[PATH_MAX] = { 0 };
int nchar = readlink("/proc/self/exe", self, sizeof self);
if (nchar < 0 || nchar >= convert(int, sizeof self))
return nil;
return string_utf8(self);
}
#elif HAVE_WINDOWS_H
static val get_self_path(void)
{
wchar_t self[MAX_PATH] = { 0 };
DWORD nchar;
SetLastError(0);
nchar = GetModuleFileNameW(NULL, self, MAX_PATH);
if (nchar == 0 ||
(nchar == MAX_PATH &&
((GetLastError() == ERROR_INSUFFICIENT_BUFFER) ||
(self[MAX_PATH - 1] != 0))))
return nil;
return string(self);
}
#elif __APPLE__
static val get_self_path(void)
{
char self[PATH_MAX] = { 0 };
uint32_t size = sizeof self;
if (_NSGetExecutablePath(self, &size) != 0)
return nil;
return string_utf8(self);
}
#elif HAVE_GETEXECNAME
static val get_self_path(void)
{
val execname = string_utf8(getexecname());
if (car(execname) == chr('/'))
return execname;
return scat3(getcwd_wrap(), chr('/'), execname);
}
#else
static val get_self_path(void)
{
char self[PATH_MAX];
if (argv[0] && realpath(argv[0], self))
return string_utf8(self);
return lit(HARD_INSTALLATION_PATH);
}
#endif
Run Code Online (Sandbox Code Playgroud)
类型val
、nil
符号和函数string
是string_utf8
解释器内部的。convert
只是一个抽象铸造的宏。当然,还需要一些头文件readlink
,realpath
等等。
该getexecname
函数是 Solaris 上的东西。似乎出于某种原因,我在处理相对路径的情况下进行了编码,在这种情况下,必须将当前目录粘贴到其上才能获得绝对路径。
后备策略是,如果argv[0]
frommain
可用,则调用realpath
它并运行它。如果argv[0]
不可用,那么我们依赖于来自Makefile
变量的硬编码安装路径。例如,如果程序安装为/usr/bin/foo
,则Makefile
配方会将其作为 插入到编译器命令行中-DHARD_INSTALLATION_PATH=/usr/bin/foo
。当然,只有当程序安装在其构建路径时,这才是正确的。
归档时间: |
|
查看次数: |
5572 次 |
最近记录: |