No interior de um interpretador de linguagem de programação, eu uso o seguinte código para obter o caminho próprio:
#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);
}
#else
static val get_self_path(void)
{
char self[PATH_MAX];
if (!progname_u8)
return nil;
if (realpath(progname_u8, self))
return string_utf8(self);
return nil;
}
#endif
O tipo val
, nil
e as funções string
e string_utf8
são internas ao interpretador. convert
é apenas uma macro que abstrai a transmissão. Naturalmente, alguns arquivos de cabeçalho são necessários para readlink
, realpath
e assim por diante.
progname_u8
é apenas uma variável global inicializada diretamente de argv[0]
. em um Unix que não é Linux, usamos isso e chamamos realpath
para obter um caminho absoluto.