Fix 1117: Use realpath in stage1 Darwin os_self_exe_path

Issue: https://github.com/ziglang/zig/issues/1117

The macOS stage1 Zig compiler should look in Zig's real absolute path
for the Zig stdlib, but os_self_exe_path looks in its path as returned
by _NSGetExecutablePath, which may be a symlink.  This means that a
symlinked Zig cannot find the Zig stdlib.

This patch fixes the issue by resolving the _NSGetExecutablePath result
to the real path using realpath() before copying the result to the
output path.
master
Bodie Solomon 2018-06-17 14:35:00 -04:00
parent d52ef95f77
commit e6b69151c0
No known key found for this signature in database
GPG Key ID: C71FE7F2B22B57F5
1 changed files with 18 additions and 2 deletions

View File

@ -989,12 +989,28 @@ int os_self_exe_path(Buf *out_path) {
}
#elif defined(ZIG_OS_DARWIN)
// How long is the executable's path?
uint32_t u32_len = 0;
int ret1 = _NSGetExecutablePath(nullptr, &u32_len);
assert(ret1 != 0);
buf_resize(out_path, u32_len);
int ret2 = _NSGetExecutablePath(buf_ptr(out_path), &u32_len);
// Allocate a buffer for this path.
Buf *path_tmp = buf_alloc_fixed(u32_len);
// Fill the buffer with the path, which may be a symlink.
int ret2 = _NSGetExecutablePath(buf_ptr(path_tmp), &u32_len);
assert(ret2 == 0);
// Make a buffer with room for the real path.
Buf *resolve_tmp = buf_alloc_fixed(PATH_MAX);
// Fill it with the real resolved path.
char *real_path = realpath(buf_ptr(path_tmp), buf_ptr(resolve_tmp));
// IEEE Std 1003.1-2017: realpath() shall return a pointer to the
// buffer containing the resolved name.
assert(real_path == buf_ptr(resolve_tmp));
// Resize out_path and copy the resulting resolved absolute path.
buf_init_from_buf(out_path, resolve_tmp);
return 0;
#elif defined(ZIG_OS_LINUX)
buf_resize(out_path, 256);